|
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