@@ -304,7 +304,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
304304 ptr : Pointer < M :: PointerTag > ,
305305 liveness : InboundsCheck ,
306306 ) -> 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 ) ? ;
308308 ptr. check_in_alloc ( allocation_size, liveness) ?;
309309 Ok ( align)
310310 }
@@ -427,27 +427,37 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
427427 }
428428 }
429429
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 ) > {
431438 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 ) ) ;
433440 }
434441 // Could also be a fn ptr or extern static
435442 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 ( ) ) ) ,
437444 Some ( AllocKind :: Static ( did) ) => {
438445 // The only way `get` couldn't have worked here is if this is an extern static
439446 assert ! ( self . tcx. is_foreign_item( did) ) ;
440447 // Use size and align of the type
441448 let ty = self . tcx . type_of ( did) ;
442449 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 ) )
450451 }
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+ } ,
451461 }
452462 }
453463
0 commit comments