about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Scherer <github35764891676564198441@oli-obk.de>2018-12-20 15:14:25 +0100
committerOliver Scherer <github35764891676564198441@oli-obk.de>2018-12-22 17:40:59 +0100
commitc8bcac56649b21ae291e9d224c7e1ddb2f5c62a0 (patch)
tree1167ce5a77f04ca13677137493d093c19615ccda
parentd8ddb47fcebf2c73e8d92d65925c4ed72d22171f (diff)
downloadrust-c8bcac56649b21ae291e9d224c7e1ddb2f5c62a0.tar.gz
rust-c8bcac56649b21ae291e9d224c7e1ddb2f5c62a0.zip
Reintroduce the original `check_bounds_ptr` checks
-rw-r--r--src/librustc_mir/interpret/memory.rs32
1 files changed, 21 insertions, 11 deletions
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index de7ad1651c1..e5245c24c8c 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -304,7 +304,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
         ptr: Pointer<M::PointerTag>,
         liveness: InboundsCheck,
     ) -> EvalResult<'tcx, Align> {
-        let (allocation_size, align) = self.get_size_and_align(ptr.alloc_id);
+        let (allocation_size, align) = self.get_size_and_align(ptr.alloc_id, liveness)?;
         ptr.check_in_alloc(allocation_size, liveness)?;
         Ok(align)
     }
@@ -427,27 +427,37 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
         }
     }
 
-    pub fn get_size_and_align(&self, id: AllocId) -> (Size, Align) {
+    /// Obtain the size and alignment of an allocation, even if that allocation has been deallocated
+    ///
+    /// If `liveness` is `InboundsCheck::Dead`, this function always returns `Ok`
+    pub fn get_size_and_align(
+        &self,
+        id: AllocId,
+        liveness: InboundsCheck,
+    ) -> EvalResult<'static, (Size, Align)> {
         if let Ok(alloc) = self.get(id) {
-            return (Size::from_bytes(alloc.bytes.len() as u64), alloc.align);
+            return Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align));
         }
         // Could also be a fn ptr or extern static
         match self.tcx.alloc_map.lock().get(id) {
-            Some(AllocKind::Function(..)) => (Size::ZERO, Align::from_bytes(1).unwrap()),
+            Some(AllocKind::Function(..)) => Ok((Size::ZERO, Align::from_bytes(1).unwrap())),
             Some(AllocKind::Static(did)) => {
                 // The only way `get` couldn't have worked here is if this is an extern static
                 assert!(self.tcx.is_foreign_item(did));
                 // Use size and align of the type
                 let ty = self.tcx.type_of(did);
                 let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap();
-                (layout.size, layout.align.abi)
-            }
-            _ => {
-                // Must be a deallocated pointer
-                *self.dead_alloc_map.get(&id).expect(
-                    "allocation missing in dead_alloc_map"
-                )
+                Ok((layout.size, layout.align.abi))
             }
+            _ => match liveness {
+                InboundsCheck::MaybeDead => {
+                    // Must be a deallocated pointer
+                    Ok(*self.dead_alloc_map.get(&id).expect(
+                        "allocation missing in dead_alloc_map"
+                    ))
+                },
+                InboundsCheck::Live => err!(DanglingPointerDeref),
+            },
         }
     }