about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2019-07-28 13:02:01 +0200
committerRalf Jung <post@ralfj.de>2019-07-28 13:26:28 +0200
commitc119291b55f2a14a2b0e13fbd3d54a9692f1066f (patch)
tree088eafcd2c09adcaf8a45217c920e266351ac848
parent828e7b685ade9d53a8f72f3509a98f2255787136 (diff)
downloadrust-c119291b55f2a14a2b0e13fbd3d54a9692f1066f.tar.gz
rust-c119291b55f2a14a2b0e13fbd3d54a9692f1066f.zip
get_size_and_align: fix handling of function pointers
-rw-r--r--src/librustc_mir/interpret/memory.rs24
1 files changed, 15 insertions, 9 deletions
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index 12be9baec13..87dd7738410 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -535,14 +535,26 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         id: AllocId,
         liveness: AllocCheck,
     ) -> InterpResult<'static, (Size, Align)> {
+        // # Regular allocations
         // Don't use `self.get` here as that will
         // a) cause cycles in case `id` refers to a static
         // b) duplicate a static's allocation in miri
         if let Some((_, alloc)) = self.alloc_map.get(id) {
             return Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align));
         }
-        // Not a local allocation, check the global `tcx.alloc_map`.
 
+        // # Function pointers
+        // (both global from `alloc_map` and local from `extra_fn_ptr_map`)
+        if let Ok(_) = self.get_fn_alloc(id) {
+            return if let AllocCheck::Dereferencable = liveness {
+                // The caller requested no function pointers.
+                err!(DerefFunctionPointer)
+            } else {
+                Ok((Size::ZERO, Align::from_bytes(1).unwrap()))
+            };
+        }
+
+        // # Statics
         // Can't do this in the match argument, we may get cycle errors since the lock would
         // be held throughout the match.
         let alloc = self.tcx.alloc_map.lock().get(id);
@@ -557,14 +569,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
                 // Need to duplicate the logic here, because the global allocations have
                 // different associated types than the interpreter-local ones.
                 Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)),
-            Some(GlobalAlloc::Function(_)) => {
-                if let AllocCheck::Dereferencable = liveness {
-                    // The caller requested no function pointers.
-                    err!(DerefFunctionPointer)
-                } else {
-                    Ok((Size::ZERO, Align::from_bytes(1).unwrap()))
-                }
-            },
+            Some(GlobalAlloc::Function(_)) =>
+                bug!("We already checked function pointers above"),
             // The rest must be dead.
             None => if let AllocCheck::MaybeDead = liveness {
                 // Deallocated pointers are allowed, we should be able to find