about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2019-07-06 14:19:04 +0200
committerRalf Jung <post@ralfj.de>2019-07-06 14:19:04 +0200
commitac4f6ab2a0ef61af3cd6a1c6966609a0b5f97b34 (patch)
tree9ce606e4fab66f2039fb92acb1b9d88778dbd985
parent9b71a8f8ba4e47c19336ceb504eb724056f96f95 (diff)
downloadrust-ac4f6ab2a0ef61af3cd6a1c6966609a0b5f97b34.tar.gz
rust-ac4f6ab2a0ef61af3cd6a1c6966609a0b5f97b34.zip
forcing instead of normalization
Normalziation does not work well for dyamically sized types
-rw-r--r--src/librustc_mir/interpret/operand.rs6
-rw-r--r--src/librustc_mir/interpret/place.rs8
-rw-r--r--src/librustc_mir/interpret/validity.rs15
3 files changed, 17 insertions, 12 deletions
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index b43c810b8e6..3d97132e539 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -217,13 +217,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     /// Normalice `place.ptr` to a `Pointer` if this is a place and not a ZST.
     /// Can be helpful to avoid lots of `force_ptr` calls later, if this place is used a lot.
     #[inline]
-    pub fn normalize_op_ptr(
+    pub fn force_op_ptr(
         &self,
         op: OpTy<'tcx, M::PointerTag>,
     ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
         match op.try_as_mplace() {
-            Ok(mplace) => Ok(self.normalize_mplace_ptr(mplace)?.into()),
-            Err(imm) => Ok(imm.into()), // Nothing to normalize
+            Ok(mplace) => Ok(self.force_mplace_ptr(mplace)?.into()),
+            Err(imm) => Ok(imm.into()), // Nothing to cast/force
         }
     }
 
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 6b8eb3fa773..50e3789ed80 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -327,15 +327,13 @@ where
         self.memory.check_ptr_access(place.ptr, size, place.align)
     }
 
-    /// Normalice `place.ptr` to a `Pointer` if this is not a ZST.
+    /// Force `place.ptr` to a `Pointer`.
     /// Can be helpful to avoid lots of `force_ptr` calls later, if this place is used a lot.
-    pub fn normalize_mplace_ptr(
+    pub fn force_mplace_ptr(
         &self,
         mut place: MPlaceTy<'tcx, M::PointerTag>,
     ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
-        if !place.layout.is_zst() {
-            place.mplace.ptr = self.force_ptr(place.mplace.ptr)?.into();
-        }
+        place.mplace.ptr = self.force_ptr(place.mplace.ptr)?.into();
         Ok(place)
     }
 
diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index bf062ac68a5..00107a536ba 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -444,7 +444,12 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
                     // `!` is a ZST and we want to validate it.
                     // Normalize before handing `place` to tracking because that will
                     // check for duplicates.
-                    let place = self.ecx.normalize_mplace_ptr(place)?;
+                    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
@@ -578,8 +583,8 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
                 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 (no cast because we normalized in validate_operand).
-                let ptr = mplace.ptr.assert_ptr();
+                // 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`.
@@ -654,8 +659,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             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
-        let op = self.normalize_op_ptr(op)?; // avoid doing ptr-to-int all the time
         visitor.visit_value(op)
     }
 }