//! Check the validity invariant of a given value, and tell the user
//! where in the value it got violated.
//! In const context, this goes even further and tries to approximate const safety.
//! That's useful because it means other passes (e.g. promotion) can rely on `const`s
//! to be const-safe.

use std::fmt::Write;
use std::ops::RangeInclusive;

use syntax_pos::symbol::{sym, Symbol};
use rustc::hir;
use rustc::ty::layout::{self, TyLayout, LayoutOf, VariantIdx};
use rustc::ty;
use rustc_data_structures::fx::FxHashSet;

use std::hash::Hash;

use super::{
    GlobalAlloc, InterpResult,
    Scalar, OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy,
};

macro_rules! throw_validation_failure {
    ($what:expr, $where:expr, $details:expr) => {{
        let where_ = path_format(&$where);
        let where_ = if where_.is_empty() {
            String::new()
        } else {
            format!(" at {}", where_)
        };
        throw_unsup!(ValidationFailure(format!(
            "encountered {}{}, but expected {}",
            $what, where_, $details,
        )))
    }};
    ($what:expr, $where:expr) => {{
        let where_ = path_format(&$where);
        let where_ = if where_.is_empty() {
            String::new()
        } else {
            format!(" at {}", where_)
        };
        throw_unsup!(ValidationFailure(format!(
            "encountered {}{}",
            $what, where_,
        )))
    }};
}

macro_rules! try_validation {
    ($e:expr, $what:expr, $where:expr, $details:expr) => {{
        match $e {
            Ok(x) => x,
            Err(_) => throw_validation_failure!($what, $where, $details),
        }
    }};

    ($e:expr, $what:expr, $where:expr) => {{
        match $e {
            Ok(x) => x,
            Err(_) => throw_validation_failure!($what, $where),
        }
    }}
}

/// We want to show a nice path to the invalid field for diagnostics,
/// but avoid string operations in the happy case where no error happens.
/// So we track a `Vec<PathElem>` where `PathElem` contains all the data we
/// need to later print something for the user.
#[derive(Copy, Clone, Debug)]
pub enum PathElem {
    Field(Symbol),
    Variant(Symbol),
    GeneratorState(VariantIdx),
    ClosureVar(Symbol),
    ArrayElem(usize),
    TupleElem(usize),
    Deref,
    Tag,
    DynDowncast,
}

/// State for tracking recursive validation of references
pub struct RefTracking<T, PATH = ()> {
    pub seen: FxHashSet<T>,
    pub todo: Vec<(T, PATH)>,
}

impl<T: Copy + Eq + Hash + std::fmt::Debug, PATH: Default> RefTracking<T, PATH> {
    pub fn empty() -> Self {
        RefTracking {
            seen: FxHashSet::default(),
            todo: vec![],
        }
    }
    pub fn new(op: T) -> Self {
        let mut ref_tracking_for_consts = RefTracking {
            seen: FxHashSet::default(),
            todo: vec![(op, PATH::default())],
        };
        ref_tracking_for_consts.seen.insert(op);
        ref_tracking_for_consts
    }

    pub fn track(&mut self, op: T, path: impl FnOnce() -> PATH) {
        if self.seen.insert(op) {
            trace!("Recursing below ptr {:#?}", op);
            let path = path();
            // Remember to come back to this later.
            self.todo.push((op, path));
        }
    }
}

/// Format a path
fn path_format(path: &Vec<PathElem>) -> String {
    use self::PathElem::*;

    let mut out = String::new();
    for elem in path.iter() {
        match elem {
            Field(name) => write!(out, ".{}", name),
            Variant(name) => write!(out, ".<downcast-variant({})>", name),
            GeneratorState(idx) => write!(out, ".<generator-state({})>", idx.index()),
            ClosureVar(name) => write!(out, ".<closure-var({})>", name),
            TupleElem(idx) => write!(out, ".{}", idx),
            ArrayElem(idx) => write!(out, "[{}]", idx),
            Deref =>
                // This does not match Rust syntax, but it is more readable for long paths -- and
                // some of the other items here also are not Rust syntax.  Actually we can't
                // even use the usual syntax because we are just showing the projections,
                // not the root.
                write!(out, ".<deref>"),
            Tag => write!(out, ".<enum-tag>"),
            DynDowncast => write!(out, ".<dyn-downcast>"),
        }.unwrap()
    }
    out
}

// Test if a range that wraps at overflow contains `test`
fn wrapping_range_contains(r: &RangeInclusive<u128>, test: u128) -> bool {
    let (lo, hi) = r.clone().into_inner();
    if lo > hi {
        // Wrapped
        (..=hi).contains(&test) || (lo..).contains(&test)
    } else {
        // Normal
        r.contains(&test)
    }
}

// Formats such that a sentence like "expected something {}" to mean
// "expected something <in the given range>" makes sense.
fn wrapping_range_format(r: &RangeInclusive<u128>, max_hi: u128) -> String {
    let (lo, hi) = r.clone().into_inner();
    debug_assert!(hi <= max_hi);
    if lo > hi {
        format!("less or equal to {}, or greater or equal to {}", hi, lo)
    } else if lo == hi {
        format!("equal to {}", lo)
    } else if lo == 0 {
        debug_assert!(hi < max_hi, "should not be printing if the range covers everything");
        format!("less or equal to {}", hi)
    } else if hi == max_hi {
        debug_assert!(lo > 0, "should not be printing if the range covers everything");
        format!("greater or equal to {}", lo)
    } else {
        format!("in the range {:?}", r)
    }
}

struct ValidityVisitor<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> {
    /// The `path` may be pushed to, but the part that is present when a function
    /// starts must not be changed!  `visit_fields` and `visit_array` rely on
    /// this stack discipline.
    path: Vec<PathElem>,
    ref_tracking_for_consts: Option<&'rt mut RefTracking<
        MPlaceTy<'tcx, M::PointerTag>,
        Vec<PathElem>,
    >>,
    ecx: &'rt InterpCx<'mir, 'tcx, M>,
}

impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M> {
    fn aggregate_field_path_elem(
        &mut self,
        layout: TyLayout<'tcx>,
        field: usize,
    ) -> PathElem {
        match layout.ty.sty {
            // generators and closures.
            ty::Closure(def_id, _) | ty::Generator(def_id, _, _) => {
                let mut name = None;
                if def_id.is_local() {
                    let tables = self.ecx.tcx.typeck_tables_of(def_id);
                    if let Some(upvars) = tables.upvar_list.get(&def_id) {
                        // Sometimes the index is beyond the number of upvars (seen
                        // for a generator).
                        if let Some((&var_hir_id, _)) = upvars.get_index(field) {
                            let node = self.ecx.tcx.hir().get(var_hir_id);
                            if let hir::Node::Binding(pat) = node {
                                if let hir::PatKind::Binding(_, _, ident, _) = pat.node {
                                    name = Some(ident.name);
                                }
                            }
                        }
                    }
                }

                PathElem::ClosureVar(name.unwrap_or_else(|| {
                    // Fall back to showing the field index.
                    sym::integer(field)
                }))
            }

            // tuples
            ty::Tuple(_) => PathElem::TupleElem(field),

            // enums
            ty::Adt(def, ..) if def.is_enum() => {
                // we might be projecting *to* a variant, or to a field *in*a variant.
                match layout.variants {
                    layout::Variants::Single { index } =>
                        // Inside a variant
                        PathElem::Field(def.variants[index].fields[field].ident.name),
                    _ => bug!(),
                }
            }

            // other ADTs
            ty::Adt(def, _) => PathElem::Field(def.non_enum_variant().fields[field].ident.name),

            // arrays/slices
            ty::Array(..) | ty::Slice(..) => PathElem::ArrayElem(field),

            // dyn traits
            ty::Dynamic(..) => PathElem::DynDowncast,

            // nothing else has an aggregate layout
            _ => bug!("aggregate_field_path_elem: got non-aggregate type {:?}", layout.ty),
        }
    }

    fn visit_elem(
        &mut self,
        new_op: OpTy<'tcx, M::PointerTag>,
        elem: PathElem,
    ) -> InterpResult<'tcx> {
        // Remember the old state
        let path_len = self.path.len();
        // Perform operation
        self.path.push(elem);
        self.visit_value(new_op)?;
        // Undo changes
        self.path.truncate(path_len);
        Ok(())
    }

    fn check_wide_ptr_meta(
        &mut self,
        meta: Option<Scalar<M::PointerTag>>,
        pointee: TyLayout<'tcx>,
    ) -> InterpResult<'tcx> {
        let tail = self.ecx.tcx.struct_tail_erasing_lifetimes(pointee.ty, self.ecx.param_env);
        match tail.sty {
            ty::Dynamic(..) => {
                let vtable = meta.unwrap();
                try_validation!(
                    self.ecx.memory.check_ptr_access(
                        vtable,
                        3*self.ecx.tcx.data_layout.pointer_size, // drop, size, align
                        self.ecx.tcx.data_layout.pointer_align.abi,
                    ),
                    "dangling or unaligned vtable pointer in wide pointer or too small vtable",
                    self.path
                );
                try_validation!(self.ecx.read_drop_type_from_vtable(vtable),
                    "invalid drop fn in vtable", self.path);
                try_validation!(self.ecx.read_size_and_align_from_vtable(vtable),
                    "invalid size or align in vtable", self.path);
                // FIXME: More checks for the vtable.
            }
            ty::Slice(..) | ty::Str => {
                let _len = try_validation!(meta.unwrap().to_usize(self.ecx),
                    "non-integer slice length in wide pointer", self.path);
                // We do not check that `len * elem_size <= isize::MAX`:
                // that is only required for references, and there it falls out of the
                // "dereferencable" check performed by Stacked Borrows.
            }
            ty::Foreign(..) => {
                // Unsized, but not wide.
            }
            _ =>
                bug!("Unexpected unsized type tail: {:?}", tail),
        }

        Ok(())
    }
}

impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
    for ValidityVisitor<'rt, 'mir, 'tcx, M>
{
    type V = OpTy<'tcx, M::PointerTag>;

    #[inline(always)]
    fn ecx(&self) -> &InterpCx<'mir, 'tcx, M> {
        &self.ecx
    }

    #[inline]
    fn visit_field(
        &mut self,
        old_op: OpTy<'tcx, M::PointerTag>,
        field: usize,
        new_op: OpTy<'tcx, M::PointerTag>
    ) -> InterpResult<'tcx> {
        let elem = self.aggregate_field_path_elem(old_op.layout, field);
        self.visit_elem(new_op, elem)
    }

    #[inline]
    fn visit_variant(
        &mut self,
        old_op: OpTy<'tcx, M::PointerTag>,
        variant_id: VariantIdx,
        new_op: OpTy<'tcx, M::PointerTag>
    ) -> InterpResult<'tcx> {
        let name = match old_op.layout.ty.sty {
            ty::Adt(adt, _) => PathElem::Variant(adt.variants[variant_id].ident.name),
            // Generators also have variants
            ty::Generator(..) => PathElem::GeneratorState(variant_id),
            _ => bug!("Unexpected type with variant: {:?}", old_op.layout.ty),
        };
        self.visit_elem(new_op, name)
    }

    #[inline]
    fn visit_value(&mut self, op: OpTy<'tcx, M::PointerTag>) -> InterpResult<'tcx>
    {
        trace!("visit_value: {:?}, {:?}", *op, op.layout);
        // Translate some possible errors to something nicer.
        match self.walk_value(op) {
            Ok(()) => Ok(()),
            Err(err) => match err.kind {
                err_unsup!(InvalidDiscriminant(val)) =>
                    throw_validation_failure!(
                        val, self.path, "a valid enum discriminant"
                    ),
                err_unsup!(ReadPointerAsBytes) =>
                    throw_validation_failure!(
                        "a pointer", self.path, "plain (non-pointer) bytes"
                    ),
                _ => Err(err),
            }
        }
    }

    fn visit_primitive(&mut self, value: OpTy<'tcx, M::PointerTag>) -> InterpResult<'tcx>
    {
        let value = self.ecx.read_immediate(value)?;
        // Go over all the primitive types
        let ty = value.layout.ty;
        match ty.sty {
            ty::Bool => {
                let value = value.to_scalar_or_undef();
                try_validation!(value.to_bool(),
                    value, self.path, "a boolean");
            },
            ty::Char => {
                let value = value.to_scalar_or_undef();
                try_validation!(value.to_char(),
                    value, self.path, "a valid unicode codepoint");
            },
            ty::Float(_) | ty::Int(_) | ty::Uint(_) => {
                // NOTE: Keep this in sync with the array optimization for int/float
                // types below!
                let size = value.layout.size;
                let value = value.to_scalar_or_undef();
                if self.ref_tracking_for_consts.is_some() {
                    // Integers/floats in CTFE: Must be scalar bits, pointers are dangerous
                    try_validation!(value.to_bits(size),
                        value, self.path, "initialized plain (non-pointer) bytes");
                } else {
                    // At run-time, for now, we accept *anything* for these types, including
                    // undef. We should fix that, but let's start low.
                }
            }
            ty::RawPtr(..) => {
                // Check pointer part.
                if self.ref_tracking_for_consts.is_some() {
                    // Integers/floats in CTFE: For consistency with integers, we do not
                    // accept undef.
                    let _ptr = try_validation!(value.to_scalar_ptr(),
                        "undefined address in raw pointer", self.path);
                } else {
                    // Remain consistent with `usize`: Accept anything.
                }

                // Check metadata.
                let meta = try_validation!(value.to_meta(),
                    "uninitialized data in wide pointer metadata", self.path);
                let layout = self.ecx.layout_of(value.layout.ty.builtin_deref(true).unwrap().ty)?;
                if layout.is_unsized() {
                    self.check_wide_ptr_meta(meta, layout)?;
                }
            }
            _ if ty.is_box() || ty.is_region_ptr() => {
                // Handle wide pointers.
                // Check metadata early, for better diagnostics
                let ptr = try_validation!(value.to_scalar_ptr(),
                    "undefined address in pointer", self.path);
                let meta = try_validation!(value.to_meta(),
                    "uninitialized data in wide pointer metadata", self.path);
                let layout = self.ecx.layout_of(value.layout.ty.builtin_deref(true).unwrap().ty)?;
                if layout.is_unsized() {
                    self.check_wide_ptr_meta(meta, layout)?;
                }
                // Make sure this is dereferencable and all.
                let (size, align) = self.ecx.size_and_align_of(meta, layout)?
                    // for the purpose of validity, consider foreign types to have
                    // alignment and size determined by the layout (size will be 0,
                    // alignment should take attributes into account).
                    .unwrap_or_else(|| (layout.size, layout.align.abi));
                let ptr: Option<_> = match
                    self.ecx.memory.check_ptr_access_align(ptr, size, Some(align))
                {
                    Ok(ptr) => ptr,
                    Err(err) => {
                        info!(
                            "{:?} did not pass access check for size {:?}, align {:?}",
                            ptr, size, align
                        );
                        match err.kind {
                            err_unsup!(InvalidNullPointerUsage) =>
                                throw_validation_failure!("NULL reference", self.path),
                            err_unsup!(AlignmentCheckFailed { required, has }) =>
                                throw_validation_failure!(format!("unaligned reference \
                                    (required {} byte alignment but found {})",
                                    required.bytes(), has.bytes()), self.path),
                            err_unsup!(ReadBytesAsPointer) =>
                                throw_validation_failure!(
                                    "dangling reference (created from integer)",
                                    self.path
                                ),
                            _ =>
                                throw_validation_failure!(
                                    "dangling reference (not entirely in bounds)",
                                    self.path
                                ),
                        }
                    }
                };
                // Recursive checking
                if let Some(ref mut ref_tracking) = self.ref_tracking_for_consts {
                    let place = self.ecx.ref_to_mplace(value)?;
                    if let Some(ptr) = ptr { // not a ZST
                        // Skip validation entirely for some external statics
                        let alloc_kind = self.ecx.tcx.alloc_map.lock().get(ptr.alloc_id);
                        if let Some(GlobalAlloc::Static(did)) = alloc_kind {
                            // `extern static` cannot be validated as they have no body.
                            // FIXME: Statics from other crates are also skipped.
                            // They might be checked at a different type, but for now we
                            // want to avoid recursing too deeply.  This is not sound!
                            if !did.is_local() || self.ecx.tcx.is_foreign_item(did) {
                                return Ok(());
                            }
                        }
                    }
                    // Proceed recursively even for ZST, no reason to skip them!
                    // `!` is a ZST and we want to validate it.
                    // Normalize before handing `place` to tracking because that will
                    // check for duplicates.
                    let place = if size.bytes() > 0 {
                        self.ecx.force_mplace_ptr(place)
                            .expect("we already bounds-checked")
                    } else {
                        place
                    };
                    let path = &self.path;
                    ref_tracking.track(place, || {
                        // We need to clone the path anyway, make sure it gets created
                        // with enough space for the additional `Deref`.
                        let mut new_path = Vec::with_capacity(path.len() + 1);
                        new_path.clone_from(path);
                        new_path.push(PathElem::Deref);
                        new_path
                    });
                }
            }
            ty::FnPtr(_sig) => {
                let value = value.to_scalar_or_undef();
                let _fn = try_validation!(
                    value.not_undef().and_then(|ptr| self.ecx.memory.get_fn(ptr)),
                    value, self.path, "a function pointer"
                );
                // FIXME: Check if the signature matches
            }
            // This should be all the primitive types
            _ => bug!("Unexpected primitive type {}", value.layout.ty)
        }
        Ok(())
    }

    fn visit_uninhabited(&mut self) -> InterpResult<'tcx>
    {
        throw_validation_failure!("a value of an uninhabited type", self.path)
    }

    fn visit_scalar(
        &mut self,
        op: OpTy<'tcx, M::PointerTag>,
        layout: &layout::Scalar,
    ) -> InterpResult<'tcx> {
        let value = self.ecx.read_scalar(op)?;
        // Determine the allowed range
        let (lo, hi) = layout.valid_range.clone().into_inner();
        // `max_hi` is as big as the size fits
        let max_hi = u128::max_value() >> (128 - op.layout.size.bits());
        assert!(hi <= max_hi);
        // We could also write `(hi + 1) % (max_hi + 1) == lo` but `max_hi + 1` overflows for `u128`
        if (lo == 0 && hi == max_hi) || (hi + 1 == lo) {
            // Nothing to check
            return Ok(());
        }
        // At least one value is excluded. Get the bits.
        let value = try_validation!(value.not_undef(),
            value,
            self.path,
            format!(
                "something {}",
                wrapping_range_format(&layout.valid_range, max_hi),
            )
        );
        let bits = match value.to_bits_or_ptr(op.layout.size, self.ecx) {
            Err(ptr) => {
                if lo == 1 && hi == max_hi {
                    // Only NULL is the niche.  So make sure the ptr is NOT NULL.
                    if self.ecx.memory.ptr_may_be_null(ptr) {
                        throw_validation_failure!(
                            "a potentially NULL pointer",
                            self.path,
                            format!(
                                "something that cannot possibly fail to be {}",
                                wrapping_range_format(&layout.valid_range, max_hi)
                            )
                        )
                    }
                    return Ok(());
                } else {
                    // Conservatively, we reject, because the pointer *could* have a bad
                    // value.
                    throw_validation_failure!(
                        "a pointer",
                        self.path,
                        format!(
                            "something that cannot possibly fail to be {}",
                            wrapping_range_format(&layout.valid_range, max_hi)
                        )
                    )
                }
            }
            Ok(data) =>
                data
        };
        // Now compare. This is slightly subtle because this is a special "wrap-around" range.
        if wrapping_range_contains(&layout.valid_range, bits) {
            Ok(())
        } else {
            throw_validation_failure!(
                bits,
                self.path,
                format!("something {}", wrapping_range_format(&layout.valid_range, max_hi))
            )
        }
    }

    fn visit_aggregate(
        &mut self,
        op: OpTy<'tcx, M::PointerTag>,
        fields: impl Iterator<Item=InterpResult<'tcx, Self::V>>,
    ) -> InterpResult<'tcx> {
        match op.layout.ty.sty {
            ty::Str => {
                let mplace = op.assert_mem_place(); // strings are never immediate
                try_validation!(self.ecx.read_str(mplace),
                    "uninitialized or non-UTF-8 data in str", self.path);
            }
            ty::Array(tys, ..) | ty::Slice(tys) if {
                // This optimization applies only for integer and floating point types
                // (i.e., types that can hold arbitrary bytes).
                match tys.sty {
                    ty::Int(..) | ty::Uint(..) | ty::Float(..) => true,
                    _ => false,
                }
            } => {
                // bailing out for zsts is ok, since the array element type can only be int/float
                if op.layout.is_zst() {
                    return Ok(());
                }
                // non-ZST array cannot be immediate, slices are never immediate
                let mplace = op.assert_mem_place();
                // This is the length of the array/slice.
                let len = mplace.len(self.ecx)?;
                // zero length slices have nothing to be checked
                if len == 0 {
                    return Ok(());
                }
                // This is the element type size.
                let ty_size = self.ecx.layout_of(tys)?.size;
                // This is the size in bytes of the whole array.
                let size = ty_size * len;
                // Size is not 0, get a pointer.
                let ptr = self.ecx.force_ptr(mplace.ptr)?;

                // NOTE: Keep this in sync with the handling of integer and float
                // types above, in `visit_primitive`.
                // In run-time mode, we accept pointers in here.  This is actually more
                // permissive than a per-element check would be, e.g., we accept
                // an &[u8] that contains a pointer even though bytewise checking would
                // reject it.  However, that's good: We don't inherently want
                // to reject those pointers, we just do not have the machinery to
                // talk about parts of a pointer.
                // We also accept undef, for consistency with the type-based checks.
                match self.ecx.memory.get(ptr.alloc_id)?.check_bytes(
                    self.ecx,
                    ptr,
                    size,
                    /*allow_ptr_and_undef*/ self.ref_tracking_for_consts.is_none(),
                ) {
                    // In the happy case, we needn't check anything else.
                    Ok(()) => {},
                    // Some error happened, try to provide a more detailed description.
                    Err(err) => {
                        // For some errors we might be able to provide extra information
                        match err.kind {
                            err_unsup!(ReadUndefBytes(offset)) => {
                                // Some byte was undefined, determine which
                                // element that byte belongs to so we can
                                // provide an index.
                                let i = (offset.bytes() / ty_size.bytes()) as usize;
                                self.path.push(PathElem::ArrayElem(i));

                                throw_validation_failure!("undefined bytes", self.path)
                            },
                            // Other errors shouldn't be possible
                            _ => return Err(err),
                        }
                    }
                }
            }
            _ => {
                self.walk_aggregate(op, fields)? // default handler
            }
        }
        Ok(())
    }
}

impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
    /// This function checks the data at `op`. `op` is assumed to cover valid memory if it
    /// is an indirect operand.
    /// It will error if the bits at the destination do not match the ones described by the layout.
    ///
    /// `ref_tracking_for_consts` can be `None` to avoid recursive checking below references.
    /// This also toggles between "run-time" (no recursion) and "compile-time" (with recursion)
    /// validation (e.g., pointer values are fine in integers at runtime) and various other const
    /// specific validation checks.
    pub fn validate_operand(
        &self,
        op: OpTy<'tcx, M::PointerTag>,
        path: Vec<PathElem>,
        ref_tracking_for_consts: Option<&mut RefTracking<
            MPlaceTy<'tcx, M::PointerTag>,
            Vec<PathElem>,
        >>,
    ) -> InterpResult<'tcx> {
        trace!("validate_operand: {:?}, {:?}", *op, op.layout.ty);

        // Construct a visitor
        let mut visitor = ValidityVisitor {
            path,
            ref_tracking_for_consts,
            ecx: self,
        };

        // Try to cast to ptr *once* instead of all the time.
        let op = self.force_op_ptr(op).unwrap_or(op);

        // Run it
        visitor.visit_value(op)
    }
}
