@@ -535,48 +535,52 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
535535 id : AllocId ,
536536 liveness : AllocCheck ,
537537 ) -> InterpResult < ' static , ( Size , Align ) > {
538+ // # Regular allocations
538539 // Don't use `self.get` here as that will
539540 // a) cause cycles in case `id` refers to a static
540541 // b) duplicate a static's allocation in miri
541- match self . alloc_map . get_or ( id, || Err ( ( ) ) ) {
542- Ok ( ( _, alloc) ) => Ok ( ( Size :: from_bytes ( alloc. bytes . len ( ) as u64 ) , alloc. align ) ) ,
543- Err ( ( ) ) => {
544- // Not a local allocation, check the global `tcx.alloc_map`.
545-
546- // Can't do this in the match argument, we may get cycle errors since the lock would
547- // be held throughout the match.
548- let alloc = self . tcx . alloc_map . lock ( ) . get ( id) ;
549- match alloc {
550- Some ( GlobalAlloc :: Static ( did) ) => {
551- // Use size and align of the type.
552- let ty = self . tcx . type_of ( did) ;
553- let layout = self . tcx . layout_of ( ParamEnv :: empty ( ) . and ( ty) ) . unwrap ( ) ;
554- Ok ( ( layout. size , layout. align . abi ) )
555- } ,
556- Some ( GlobalAlloc :: Memory ( alloc) ) =>
557- // Need to duplicate the logic here, because the global allocations have
558- // different associated types than the interpreter-local ones.
559- Ok ( ( Size :: from_bytes ( alloc. bytes . len ( ) as u64 ) , alloc. align ) ) ,
560- Some ( GlobalAlloc :: Function ( _) ) => {
561- if let AllocCheck :: Dereferencable = liveness {
562- // The caller requested no function pointers.
563- err ! ( DerefFunctionPointer )
564- } else {
565- Ok ( ( Size :: ZERO , Align :: from_bytes ( 1 ) . unwrap ( ) ) )
566- }
567- } ,
568- // The rest must be dead.
569- None => if let AllocCheck :: MaybeDead = liveness {
570- // Deallocated pointers are allowed, we should be able to find
571- // them in the map.
572- Ok ( * self . dead_alloc_map . get ( & id)
573- . expect ( "deallocated pointers should all be recorded in \
574- `dead_alloc_map`") )
575- } else {
576- err ! ( DanglingPointerDeref )
577- } ,
578- }
579- }
542+ if let Some ( ( _, alloc) ) = self . alloc_map . get ( id) {
543+ return Ok ( ( Size :: from_bytes ( alloc. bytes . len ( ) as u64 ) , alloc. align ) ) ;
544+ }
545+
546+ // # Function pointers
547+ // (both global from `alloc_map` and local from `extra_fn_ptr_map`)
548+ if let Ok ( _) = self . get_fn_alloc ( id) {
549+ return if let AllocCheck :: Dereferencable = liveness {
550+ // The caller requested no function pointers.
551+ err ! ( DerefFunctionPointer )
552+ } else {
553+ Ok ( ( Size :: ZERO , Align :: from_bytes ( 1 ) . unwrap ( ) ) )
554+ } ;
555+ }
556+
557+ // # Statics
558+ // Can't do this in the match argument, we may get cycle errors since the lock would
559+ // be held throughout the match.
560+ let alloc = self . tcx . alloc_map . lock ( ) . get ( id) ;
561+ match alloc {
562+ Some ( GlobalAlloc :: Static ( did) ) => {
563+ // Use size and align of the type.
564+ let ty = self . tcx . type_of ( did) ;
565+ let layout = self . tcx . layout_of ( ParamEnv :: empty ( ) . and ( ty) ) . unwrap ( ) ;
566+ Ok ( ( layout. size , layout. align . abi ) )
567+ } ,
568+ Some ( GlobalAlloc :: Memory ( alloc) ) =>
569+ // Need to duplicate the logic here, because the global allocations have
570+ // different associated types than the interpreter-local ones.
571+ Ok ( ( Size :: from_bytes ( alloc. bytes . len ( ) as u64 ) , alloc. align ) ) ,
572+ Some ( GlobalAlloc :: Function ( _) ) =>
573+ bug ! ( "We already checked function pointers above" ) ,
574+ // The rest must be dead.
575+ None => if let AllocCheck :: MaybeDead = liveness {
576+ // Deallocated pointers are allowed, we should be able to find
577+ // them in the map.
578+ Ok ( * self . dead_alloc_map . get ( & id)
579+ . expect ( "deallocated pointers should all be recorded in \
580+ `dead_alloc_map`") )
581+ } else {
582+ err ! ( DanglingPointerDeref )
583+ } ,
580584 }
581585 }
582586
0 commit comments