use rustc::hir::{self, def_id::DefId};
use rustc::mir::interpret::ConstEvalErr;
use rustc::mir;
-use rustc::ty::{self, TyCtxt, Instance, query::TyCtxtAt};
-use rustc::ty::layout::{self, LayoutOf, TyLayout};
+use rustc::ty::{self, Ty, TyCtxt, Instance, query::TyCtxtAt};
+use rustc::ty::layout::{self, Size, LayoutOf, TyLayout};
use rustc::ty::subst::Subst;
use rustc_data_structures::indexed_vec::IndexVec;
use rustc_data_structures::fx::FxHashMap;
use syntax::ast::Mutability;
use syntax::source_map::{Span, DUMMY_SP};
-use rustc::mir::interpret::{
- EvalResult, EvalError, EvalErrorKind, GlobalId,
- Scalar, Allocation, AllocId, ConstValue,
-};
use interpret::{self,
- PlaceTy, MPlaceTy, MemPlace, OpTy, Operand, Value,
- EvalContext, StackPopCleanup, MemoryKind,
+ PlaceTy, MemPlace, OpTy, Operand, Value, Pointer, Scalar, ConstValue,
+ EvalResult, EvalError, EvalErrorKind, GlobalId, EvalContext, StackPopCleanup,
+ Allocation, AllocId, MemoryKind,
snapshot,
};
#[inline(always)]
fn tag_reference(
_ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
- _place: MPlaceTy<'tcx, Self::PointerTag>,
+ _ptr: Pointer<Self::PointerTag>,
+ _pointee_ty: Ty<'tcx>,
+ _pointee_size: Size,
_borrow_kind: mir::BorrowKind,
) -> EvalResult<'tcx, Self::PointerTag> {
Ok(())
}
+
+ #[inline(always)]
+ fn tag_dereference(
+ _ecx: &EvalContext<'a, 'mir, 'tcx, Self>,
+ _ptr: Pointer<Self::PointerTag>,
+ _ptr_ty: Ty<'tcx>,
+ ) -> EvalResult<'tcx, Self::PointerTag> {
+ Ok(())
+ }
}
/// Project to a field of a (variant of a) const
use rustc::hir::def_id::DefId;
use rustc::mir;
-use rustc::ty::{self, layout::{Size, TyLayout}, query::TyCtxtAt};
+use rustc::ty::{self, Ty, layout::{Size, TyLayout}, query::TyCtxtAt};
use super::{
Allocation, AllocId, EvalResult, Scalar,
- EvalContext, PlaceTy, OpTy, MPlaceTy, Pointer, MemoryKind,
+ EvalContext, PlaceTy, OpTy, Pointer, MemoryKind,
};
/// Classifying memory accesses
}
/// Executed when evaluating the `&` operator: Creating a new reference.
- /// This has the chance to adjust the tag. It is only ever called if the
- /// pointer in `place` is really a pointer, not another scalar.
+ /// This has the chance to adjust the tag.
fn tag_reference(
ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
- place: MPlaceTy<'tcx, Self::PointerTag>,
+ ptr: Pointer<Self::PointerTag>,
+ pointee_ty: Ty<'tcx>,
+ pointee_size: Size,
borrow_kind: mir::BorrowKind,
) -> EvalResult<'tcx, Self::PointerTag>;
+ /// Executed when evaluating the `*` operator: Following a reference.
+ /// This has the change to adjust the tag.
+ fn tag_dereference(
+ ecx: &EvalContext<'a, 'mir, 'tcx, Self>,
+ ptr: Pointer<Self::PointerTag>,
+ ptr_ty: Ty<'tcx>,
+ ) -> EvalResult<'tcx, Self::PointerTag>;
+
/// Execute a validation operation
#[inline]
fn validation_op(
&self,
val: ValTy<'tcx, M::PointerTag>,
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
+ let ptr = match val.to_scalar_ptr()? {
+ Scalar::Ptr(ptr) => {
+ // Machine might want to track the `*` operator
+ let tag = M::tag_dereference(self, ptr, val.layout.ty)?;
+ Scalar::Ptr(Pointer::new_with_tag(ptr.alloc_id, ptr.offset, tag))
+ }
+ scalar @ Scalar::Bits { .. } => scalar,
+ };
+
let pointee_type = val.layout.ty.builtin_deref(true).unwrap().ty;
let layout = self.layout_of(pointee_type)?;
let align = layout.align;
+
let mplace = match *val {
- Value::Scalar(ptr) =>
- MemPlace { ptr: ptr.not_undef()?, align, meta: None },
- Value::ScalarPair(ptr, meta) =>
- MemPlace { ptr: ptr.not_undef()?, align, meta: Some(meta.not_undef()?) },
+ Value::Scalar(_) =>
+ MemPlace { ptr, align, meta: None },
+ Value::ScalarPair(_, meta) =>
+ MemPlace { ptr, align, meta: Some(meta.not_undef()?) },
};
Ok(MPlaceTy { mplace, layout })
}
) -> EvalResult<'tcx, Value<M::PointerTag>> {
let ptr = match place.ptr {
Scalar::Ptr(ptr) => {
- let tag = M::tag_reference(self, place, borrow_kind)?;
+ // Machine might want to track the `&` operator
+ let (size, _) = self.size_and_align_of_mplace(place)?
+ .expect("create_ref cannot determine size");
+ let tag = M::tag_reference(self, ptr, place.layout.ty, size, borrow_kind)?;
Scalar::Ptr(Pointer::new_with_tag(ptr.alloc_id, ptr.offset, tag))
},
scalar @ Scalar::Bits { .. } => scalar,