diff options
| author | Ralf Jung <post@ralfj.de> | 2019-06-30 15:29:04 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2019-07-04 10:38:54 +0200 |
| commit | 486720f0800fd53cb0466f20bbba840798fe5da3 (patch) | |
| tree | 786b2f5f1a9758d56f0156a4d6cb0f82adff1084 | |
| parent | 5612feb5133d24caaf68f18e9ae8812ecbaa0ba3 (diff) | |
fix determinig the size of foreign static allocations
| -rw-r--r-- | src/librustc_mir/interpret/memory.rs | 24 |
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) |
