@@ -304,7 +304,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
304
304
ptr : Pointer < M :: PointerTag > ,
305
305
liveness : InboundsCheck ,
306
306
) -> EvalResult < ' tcx , Align > {
307
- let ( allocation_size, align) = self . get_size_and_align ( ptr. alloc_id ) ;
307
+ let ( allocation_size, align) = self . get_size_and_align ( ptr. alloc_id , liveness ) ? ;
308
308
ptr. check_in_alloc ( allocation_size, liveness) ?;
309
309
Ok ( align)
310
310
}
@@ -427,27 +427,37 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
427
427
}
428
428
}
429
429
430
- pub fn get_size_and_align ( & self , id : AllocId ) -> ( Size , Align ) {
430
+ /// Obtain the size and alignment of an allocation, even if that allocation has been deallocated
431
+ ///
432
+ /// If `liveness` is `InboundsCheck::Dead`, this function always returns `Ok`
433
+ pub fn get_size_and_align (
434
+ & self ,
435
+ id : AllocId ,
436
+ liveness : InboundsCheck ,
437
+ ) -> EvalResult < ' static , ( Size , Align ) > {
431
438
if let Ok ( alloc) = self . get ( id) {
432
- return ( Size :: from_bytes ( alloc. bytes . len ( ) as u64 ) , alloc. align ) ;
439
+ return Ok ( ( Size :: from_bytes ( alloc. bytes . len ( ) as u64 ) , alloc. align ) ) ;
433
440
}
434
441
// Could also be a fn ptr or extern static
435
442
match self . tcx . alloc_map . lock ( ) . get ( id) {
436
- Some ( AllocKind :: Function ( ..) ) => ( Size :: ZERO , Align :: from_bytes ( 1 ) . unwrap ( ) ) ,
443
+ Some ( AllocKind :: Function ( ..) ) => Ok ( ( Size :: ZERO , Align :: from_bytes ( 1 ) . unwrap ( ) ) ) ,
437
444
Some ( AllocKind :: Static ( did) ) => {
438
445
// The only way `get` couldn't have worked here is if this is an extern static
439
446
assert ! ( self . tcx. is_foreign_item( did) ) ;
440
447
// Use size and align of the type
441
448
let ty = self . tcx . type_of ( did) ;
442
449
let layout = self . tcx . layout_of ( ParamEnv :: empty ( ) . and ( ty) ) . unwrap ( ) ;
443
- ( layout. size , layout. align . abi )
444
- }
445
- _ => {
446
- // Must be a deallocated pointer
447
- * self . dead_alloc_map . get ( & id) . expect (
448
- "allocation missing in dead_alloc_map"
449
- )
450
+ Ok ( ( layout. size , layout. align . abi ) )
450
451
}
452
+ _ => match liveness {
453
+ InboundsCheck :: MaybeDead => {
454
+ // Must be a deallocated pointer
455
+ Ok ( * self . dead_alloc_map . get ( & id) . expect (
456
+ "allocation missing in dead_alloc_map"
457
+ ) )
458
+ } ,
459
+ InboundsCheck :: Live => err ! ( DanglingPointerDeref ) ,
460
+ } ,
451
461
}
452
462
}
453
463
0 commit comments