@@ -10,7 +10,7 @@ use std::collections::VecDeque;
10
10
use std:: ptr;
11
11
use std:: borrow:: Cow ;
12
12
13
- use rustc:: ty:: { self , Instance , query:: TyCtxtAt } ;
13
+ use rustc:: ty:: { self , Instance , ParamEnv , query:: TyCtxtAt } ;
14
14
use rustc:: ty:: layout:: { Align , TargetDataLayout , Size , HasDataLayout } ;
15
15
use rustc_data_structures:: fx:: { FxHashSet , FxHashMap } ;
16
16
@@ -536,19 +536,33 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
536
536
) -> InterpResult < ' static , ( Size , Align ) > {
537
537
// Regular allocations.
538
538
if let Ok ( alloc) = self . get ( id) {
539
- Ok ( ( Size :: from_bytes ( alloc. bytes . len ( ) as u64 ) , alloc. align ) )
539
+ return Ok ( ( Size :: from_bytes ( alloc. bytes . len ( ) as u64 ) , alloc. align ) ) ;
540
540
}
541
541
// Function pointers.
542
- else if let Ok ( _) = self . get_fn_alloc ( id) {
543
- if let AllocCheck :: Dereferencable = liveness {
542
+ if let Ok ( _) = self . get_fn_alloc ( id) {
543
+ return if let AllocCheck :: Dereferencable = liveness {
544
544
// The caller requested no function pointers.
545
545
err ! ( DerefFunctionPointer )
546
546
} else {
547
547
Ok ( ( Size :: ZERO , Align :: from_bytes ( 1 ) . unwrap ( ) ) )
548
+ } ;
549
+ }
550
+ // Foreign statics.
551
+ // Can't do this in the match argument, we may get cycle errors since the lock would
552
+ // be held throughout the match.
553
+ let alloc = self . tcx . alloc_map . lock ( ) . get ( id) ;
554
+ match alloc {
555
+ Some ( GlobalAlloc :: Static ( did) ) => {
556
+ assert ! ( self . tcx. is_foreign_item( did) ) ;
557
+ // Use size and align of the type
558
+ let ty = self . tcx . type_of ( did) ;
559
+ let layout = self . tcx . layout_of ( ParamEnv :: empty ( ) . and ( ty) ) . unwrap ( ) ;
560
+ return Ok ( ( layout. size , layout. align . abi ) ) ;
548
561
}
562
+ _ => { }
549
563
}
550
564
// The rest must be dead.
551
- else if let AllocCheck :: MaybeDead = liveness {
565
+ if let AllocCheck :: MaybeDead = liveness {
552
566
// Deallocated pointers are allowed, we should be able to find
553
567
// them in the map.
554
568
Ok ( * self . dead_alloc_map . get ( & id)
0 commit comments