File tree 3 files changed +39
-1
lines changed
compiler/rustc_mir_transform/src
3 files changed +39
-1
lines changed Original file line number Diff line number Diff line change @@ -90,6 +90,7 @@ use rustc_hir::def::DefKind;
90
90
use rustc_index:: bit_set:: BitSet ;
91
91
use rustc_index:: IndexVec ;
92
92
use rustc_macros:: newtype_index;
93
+ use rustc_middle:: mir:: interpret:: GlobalAlloc ;
93
94
use rustc_middle:: mir:: visit:: * ;
94
95
use rustc_middle:: mir:: * ;
95
96
use rustc_middle:: ty:: adjustment:: PointerCoercion ;
@@ -922,7 +923,11 @@ fn op_to_prop_const<'tcx>(
922
923
let pointer = mplace. ptr ( ) . into_pointer_or_addr ( ) . ok ( ) ?;
923
924
let ( alloc_id, offset) = pointer. into_parts ( ) ;
924
925
intern_const_alloc_for_constprop ( ecx, alloc_id) . ok ( ) ?;
925
- return Some ( ConstValue :: Indirect { alloc_id, offset } ) ;
926
+ if matches ! ( ecx. tcx. global_alloc( alloc_id) , GlobalAlloc :: Memory ( _) ) {
927
+ // `alloc_id` may point to a static. Codegen will choke on an `Indirect` with anything
928
+ // by `GlobalAlloc::Memory`, so do fall through to copying if needed.
929
+ return Some ( ConstValue :: Indirect { alloc_id, offset } ) ;
930
+ }
926
931
}
927
932
928
933
// Everything failed: create a new allocation to hold the data.
Original file line number Diff line number Diff line change
1
+ - // MIR for `indirect_static` before GVN
2
+ + // MIR for `indirect_static` after GVN
3
+
4
+ fn indirect_static() -> () {
5
+ let mut _0: ();
6
+ let mut _1: &std::option::Option<u8>;
7
+ let mut _2: u8;
8
+
9
+ bb0: {
10
+ _1 = const {ALLOC0: &Option<u8>};
11
+ _2 = (((*_1) as variant#1).0: u8);
12
+ return;
13
+ }
14
+ }
15
+
16
+ ALLOC0 (static: A, size: 2, align: 1) {
17
+ 00 __ │ .░
18
+ }
19
+
Original file line number Diff line number Diff line change @@ -597,6 +597,18 @@ fn fn_pointers() {
597
597
opaque ( cg) ;
598
598
}
599
599
600
+ /// Verify that we do not create a `ConstValue::Indirect` backed by a static's AllocId.
601
+ #[ custom_mir( dialect = "analysis" ) ]
602
+ fn indirect_static ( ) {
603
+ static A : Option < u8 > = None ;
604
+
605
+ mir ! ( {
606
+ let ptr = Static ( A ) ;
607
+ let out = Field :: <u8 >( Variant ( * ptr, 1 ) , 0 ) ;
608
+ Return ( )
609
+ } )
610
+ }
611
+
600
612
fn main ( ) {
601
613
subexpression_elimination ( 2 , 4 , 5 ) ;
602
614
wrap_unwrap ( 5 ) ;
@@ -614,6 +626,7 @@ fn main() {
614
626
assert_eq ! ( direct, indirect) ;
615
627
repeat ( ) ;
616
628
fn_pointers ( ) ;
629
+ indirect_static ( ) ;
617
630
}
618
631
619
632
#[ inline( never) ]
@@ -639,3 +652,4 @@ fn identity<T>(x: T) -> T {
639
652
// EMIT_MIR gvn.duplicate_slice.GVN.diff
640
653
// EMIT_MIR gvn.repeat.GVN.diff
641
654
// EMIT_MIR gvn.fn_pointers.GVN.diff
655
+ // EMIT_MIR gvn.indirect_static.GVN.diff
You can’t perform that action at this time.
0 commit comments