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