|
19 | 19 | use std::collections::VecDeque; |
20 | 20 | use std::ptr; |
21 | 21 |
|
22 | | -use rustc::ty::{self, Instance, query::TyCtxtAt}; |
| 22 | +use rustc::ty::{self, Instance, ParamEnv, query::TyCtxtAt}; |
23 | 23 | use rustc::ty::layout::{self, Align, TargetDataLayout, Size, HasDataLayout}; |
24 | 24 | use rustc::mir::interpret::{Pointer, AllocId, Allocation, ConstValue, GlobalId, |
25 | 25 | EvalResult, Scalar, EvalErrorKind, AllocType, PointerArithmetic, |
@@ -235,7 +235,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { |
235 | 235 | // Check non-NULL/Undef, extract offset |
236 | 236 | let (offset, alloc_align) = match ptr { |
237 | 237 | Scalar::Ptr(ptr) => { |
238 | | - let (size, align) = self.get_size_and_align(ptr.alloc_id)?; |
| 238 | + let (size, align) = self.get_size_and_align(ptr.alloc_id); |
239 | 239 | // check this is not NULL -- which we can ensure only if this is in-bounds |
240 | 240 | // of some (potentially dead) allocation. |
241 | 241 | if ptr.offset > size { |
@@ -359,19 +359,28 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { |
359 | 359 | } |
360 | 360 | } |
361 | 361 |
|
362 | | - pub fn get_size_and_align(&self, id: AllocId) -> EvalResult<'tcx, (Size, Align)> { |
363 | | - Ok(match self.get(id) { |
364 | | - Ok(alloc) => (Size::from_bytes(alloc.bytes.len() as u64), alloc.align), |
365 | | - Err(err) => match err.kind { |
366 | | - EvalErrorKind::DanglingPointerDeref => |
367 | | - // This should be in the dead allocation map |
368 | | - *self.dead_alloc_map.get(&id).expect( |
369 | | - "allocation missing in dead_alloc_map" |
370 | | - ), |
371 | | - // E.g. a function ptr allocation |
372 | | - _ => return Err(err) |
| 362 | + pub fn get_size_and_align(&self, id: AllocId) -> (Size, Align) { |
| 363 | + if let Ok(alloc) = self.get(id) { |
| 364 | + return (Size::from_bytes(alloc.bytes.len() as u64), alloc.align); |
| 365 | + } |
| 366 | + // Could also be a fn ptr or extern static |
| 367 | + match self.tcx.alloc_map.lock().get(id) { |
| 368 | + Some(AllocType::Function(..)) => (Size::ZERO, Align::from_bytes(1, 1).unwrap()), |
| 369 | + Some(AllocType::Static(did)) => { |
| 370 | + // The only way `get` couldnÄt have worked here is if this is an extern static |
| 371 | + assert!(self.tcx.is_foreign_item(did)); |
| 372 | + // Use size and align of the type |
| 373 | + let ty = self.tcx.type_of(did); |
| 374 | + let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap(); |
| 375 | + (layout.size, layout.align) |
373 | 376 | } |
374 | | - }) |
| 377 | + _ => { |
| 378 | + // Must be a deallocated pointer |
| 379 | + *self.dead_alloc_map.get(&id).expect( |
| 380 | + "allocation missing in dead_alloc_map" |
| 381 | + ) |
| 382 | + } |
| 383 | + } |
375 | 384 | } |
376 | 385 |
|
377 | 386 | pub fn get_mut( |
|
0 commit comments