about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2018-10-16 17:00:39 +0200
committerRalf Jung <post@ralfj.de>2018-10-18 12:08:23 +0200
commitd61db93c15105561b5105f03837ddf0ac3dbee4e (patch)
tree2620efafb5027d06fc97a47a1dffc6b4a7f2ec30
parent5f20b16934373228b7d2ecae6dda708ae820b055 (diff)
downloadrust-d61db93c15105561b5105f03837ddf0ac3dbee4e.tar.gz
rust-d61db93c15105561b5105f03837ddf0ac3dbee4e.zip
also hook dereferencing
-rw-r--r--src/librustc_mir/const_eval.rs26
-rw-r--r--src/librustc_mir/interpret/machine.rs19
-rw-r--r--src/librustc_mir/interpret/place.rs23
3 files changed, 49 insertions, 19 deletions
diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index baf6a4ecaa0..66fd5edcc90 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -19,8 +19,8 @@ use std::collections::hash_map::Entry;
 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;
@@ -28,13 +28,10 @@ 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 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
     #[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
diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs
index e30874ce7b3..5dd33ec551d 100644
--- a/src/librustc_mir/interpret/machine.rs
+++ b/src/librustc_mir/interpret/machine.rs
@@ -17,11 +17,11 @@ use std::hash::Hash;
 
 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 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
     }
 
     /// 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(
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 51406a686bc..1b319b01297 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -264,14 +264,24 @@ where
         &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 @@ where
     ) -> 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,