about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2019-06-30 15:29:04 +0200
committerRalf Jung <post@ralfj.de>2019-07-04 10:38:54 +0200
commit486720f0800fd53cb0466f20bbba840798fe5da3 (patch)
tree786b2f5f1a9758d56f0156a4d6cb0f82adff1084
parent5612feb5133d24caaf68f18e9ae8812ecbaa0ba3 (diff)
fix determinig the size of foreign static allocations
-rw-r--r--src/librustc_mir/interpret/memory.rs24
1 files changed, 19 insertions, 5 deletions
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index fab559bf39d..bed531504d3 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -10,7 +10,7 @@ use std::collections::VecDeque;
 use std::ptr;
 use std::borrow::Cow;
 
-use rustc::ty::{self, Instance, query::TyCtxtAt};
+use rustc::ty::{self, Instance, ParamEnv, query::TyCtxtAt};
 use rustc::ty::layout::{Align, TargetDataLayout, Size, HasDataLayout};
 use rustc_data_structures::fx::{FxHashSet, FxHashMap};
 
@@ -536,19 +536,33 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
     ) -> InterpResult<'static, (Size, Align)> {
         // Regular allocations.
         if let Ok(alloc) = self.get(id) {
-            Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align))
+            return Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align));
         }
         // Function pointers.
-        else if let Ok(_) = self.get_fn_alloc(id) {
-            if let AllocCheck::Dereferencable = liveness {
+        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()))
+            };
+        }
+        // Foreign 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);
+        match alloc {
+            Some(GlobalAlloc::Static(did)) => {
+                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();
+                return Ok((layout.size, layout.align.abi));
             }
+            _ => {}
         }
         // The rest must be dead.
-        else if let AllocCheck::MaybeDead = liveness {
+        if let AllocCheck::MaybeDead = liveness {
             // Deallocated pointers are allowed, we should be able to find
             // them in the map.
             Ok(*self.dead_alloc_map.get(&id)