Verify that the alloc_id is Memory.

This commit is contained in:
Camille GILLOT 2023-10-22 14:49:00 +00:00
parent c4cc9ca060
commit d80eb3a498
4 changed files with 58 additions and 1 deletions

View File

@ -90,6 +90,7 @@ use rustc_hir::def::DefKind;
use rustc_index::bit_set::BitSet;
use rustc_index::IndexVec;
use rustc_macros::newtype_index;
use rustc_middle::mir::interpret::GlobalAlloc;
use rustc_middle::mir::visit::*;
use rustc_middle::mir::*;
use rustc_middle::ty::adjustment::PointerCoercion;
@ -922,7 +923,11 @@ fn op_to_prop_const<'tcx>(
let pointer = mplace.ptr().into_pointer_or_addr().ok()?;
let (alloc_id, offset) = pointer.into_parts();
intern_const_alloc_for_constprop(ecx, alloc_id).ok()?;
return Some(ConstValue::Indirect { alloc_id, offset });
if matches!(ecx.tcx.global_alloc(alloc_id), GlobalAlloc::Memory(_)) {
// `alloc_id` may point to a static. Codegen will choke on an `Indirect` with anything
// by `GlobalAlloc::Memory`, so do fall through to copying if needed.
return Some(ConstValue::Indirect { alloc_id, offset });
}
}
// Everything failed: create a new allocation to hold the data.

View File

@ -0,0 +1,19 @@
- // MIR for `indirect_static` before GVN
+ // MIR for `indirect_static` after GVN
fn indirect_static() -> () {
let mut _0: ();
let mut _1: &std::option::Option<u8>;
let mut _2: u8;
bb0: {
_1 = const {ALLOC0: &Option<u8>};
_2 = (((*_1) as variant#1).0: u8);
return;
}
}
ALLOC0 (static: A, size: 2, align: 1) {
00 __ │ .░
}

View File

@ -0,0 +1,19 @@
- // MIR for `indirect_static` before GVN
+ // MIR for `indirect_static` after GVN
fn indirect_static() -> () {
let mut _0: ();
let mut _1: &std::option::Option<u8>;
let mut _2: u8;
bb0: {
_1 = const {ALLOC0: &Option<u8>};
_2 = (((*_1) as variant#1).0: u8);
return;
}
}
ALLOC0 (static: A, size: 2, align: 1) {
00 __ │ .░
}

View File

@ -597,6 +597,18 @@ fn fn_pointers() {
opaque(cg);
}
/// Verify that we do not create a `ConstValue::Indirect` backed by a static's AllocId.
#[custom_mir(dialect = "analysis")]
fn indirect_static() {
static A: Option<u8> = None;
mir!({
let ptr = Static(A);
let out = Field::<u8>(Variant(*ptr, 1), 0);
Return()
})
}
fn main() {
subexpression_elimination(2, 4, 5);
wrap_unwrap(5);
@ -614,6 +626,7 @@ fn main() {
assert_eq!(direct, indirect);
repeat();
fn_pointers();
indirect_static();
}
#[inline(never)]
@ -639,3 +652,4 @@ fn identity<T>(x: T) -> T {
// EMIT_MIR gvn.duplicate_slice.GVN.diff
// EMIT_MIR gvn.repeat.GVN.diff
// EMIT_MIR gvn.fn_pointers.GVN.diff
// EMIT_MIR gvn.indirect_static.GVN.diff