Skip to content

Commit a14bc98

Browse files
committed
Verify that the alloc_id is Memory.
1 parent d191caf commit a14bc98

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed

compiler/rustc_mir_transform/src/gvn.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ use rustc_hir::def::DefKind;
9090
use rustc_index::bit_set::BitSet;
9191
use rustc_index::IndexVec;
9292
use rustc_macros::newtype_index;
93+
use rustc_middle::mir::interpret::GlobalAlloc;
9394
use rustc_middle::mir::visit::*;
9495
use rustc_middle::mir::*;
9596
use rustc_middle::ty::adjustment::PointerCoercion;
@@ -922,7 +923,11 @@ fn op_to_prop_const<'tcx>(
922923
let pointer = mplace.ptr().into_pointer_or_addr().ok()?;
923924
let (alloc_id, offset) = pointer.into_parts();
924925
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+
}
926931
}
927932

928933
// Everything failed: create a new allocation to hold the data.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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+

tests/mir-opt/gvn.rs

+14
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,18 @@ fn fn_pointers() {
597597
opaque(cg);
598598
}
599599

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+
600612
fn main() {
601613
subexpression_elimination(2, 4, 5);
602614
wrap_unwrap(5);
@@ -614,6 +626,7 @@ fn main() {
614626
assert_eq!(direct, indirect);
615627
repeat();
616628
fn_pointers();
629+
indirect_static();
617630
}
618631

619632
#[inline(never)]
@@ -639,3 +652,4 @@ fn identity<T>(x: T) -> T {
639652
// EMIT_MIR gvn.duplicate_slice.GVN.diff
640653
// EMIT_MIR gvn.repeat.GVN.diff
641654
// EMIT_MIR gvn.fn_pointers.GVN.diff
655+
// EMIT_MIR gvn.indirect_static.GVN.diff

0 commit comments

Comments
 (0)