]> git.lizzy.rs Git - rust.git/commitdiff
also hook dereferencing
authorRalf Jung <post@ralfj.de>
Tue, 16 Oct 2018 15:00:39 +0000 (17:00 +0200)
committerRalf Jung <post@ralfj.de>
Thu, 18 Oct 2018 10:08:23 +0000 (12:08 +0200)
src/librustc_mir/const_eval.rs
src/librustc_mir/interpret/machine.rs
src/librustc_mir/interpret/place.rs

index baf6a4ecaa02accc66f6b116780cc3b086c7d2df..66fd5edcc90bb2282011cfb93444d8b1a9f8b01e 100644 (file)
@@ -19,8 +19,8 @@
 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,
 };
 
@@ -468,11 +465,22 @@ fn before_terminator(ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>) -> EvalResult<
     #[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
index e30874ce7b386e3b4d469ac291525e93bdc78525..5dd33ec551d7f3293e6807640bae787d418c411e 100644 (file)
 
 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
@@ -199,14 +199,23 @@ fn memory_deallocated(
     }
 
     /// 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(
index 51406a686bcc96f846229a7f1cb39158363012db..1b319b012978f5d693e86194cde10166ab67d71b 100644 (file)
@@ -264,14 +264,24 @@ pub fn ref_to_mplace(
         &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 })
     }
@@ -285,7 +295,10 @@ pub fn create_ref(
     ) -> 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,