mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 05:51:58 +00:00
fix ICE with extra-const-ub-checks
This commit is contained in:
parent
c0941dfb5a
commit
d7ee421870
@ -81,7 +81,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
|
||||
}
|
||||
|
||||
/// The `InterpCx` is only meant to be used to do field and index projections into constants for
|
||||
/// `simd_shuffle` and const patterns in match arms.
|
||||
/// `simd_shuffle` and const patterns in match arms. It never performs alignment checks.
|
||||
///
|
||||
/// The function containing the `match` that is currently being analyzed may have generic bounds
|
||||
/// that inform us about the generic bounds of the constant. E.g., using an associated constant
|
||||
@ -98,7 +98,11 @@ pub(super) fn mk_eval_cx<'mir, 'tcx>(
|
||||
tcx,
|
||||
root_span,
|
||||
param_env,
|
||||
CompileTimeInterpreter::new(tcx.const_eval_limit(), can_access_statics),
|
||||
CompileTimeInterpreter::new(
|
||||
tcx.const_eval_limit(),
|
||||
can_access_statics,
|
||||
/*check_alignment:*/ false,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@ -203,7 +207,13 @@ pub(crate) fn turn_into_const_value<'tcx>(
|
||||
let cid = key.value;
|
||||
let def_id = cid.instance.def.def_id();
|
||||
let is_static = tcx.is_static(def_id);
|
||||
let ecx = mk_eval_cx(tcx, tcx.def_span(key.value.instance.def_id()), key.param_env, is_static);
|
||||
// This is just accessing an already computed constant, so no need to check alginment here.
|
||||
let ecx = mk_eval_cx(
|
||||
tcx,
|
||||
tcx.def_span(key.value.instance.def_id()),
|
||||
key.param_env,
|
||||
/*can_access_statics:*/ is_static,
|
||||
);
|
||||
|
||||
let mplace = ecx.raw_const_to_mplace(constant).expect(
|
||||
"can only fail if layout computation failed, \
|
||||
@ -300,7 +310,11 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
|
||||
key.param_env,
|
||||
// Statics (and promoteds inside statics) may access other statics, because unlike consts
|
||||
// they do not have to behave "as if" they were evaluated at runtime.
|
||||
CompileTimeInterpreter::new(tcx.const_eval_limit(), /*can_access_statics:*/ is_static),
|
||||
CompileTimeInterpreter::new(
|
||||
tcx.const_eval_limit(),
|
||||
/*can_access_statics:*/ is_static,
|
||||
/*check_alignment:*/ tcx.sess.opts.unstable_opts.extra_const_ub_checks,
|
||||
),
|
||||
);
|
||||
|
||||
let res = ecx.load_mir(cid.instance.def, cid.promoted);
|
||||
|
@ -101,14 +101,22 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> {
|
||||
/// * Pointers to allocations inside of statics can never leak outside, to a non-static global.
|
||||
/// This boolean here controls the second part.
|
||||
pub(super) can_access_statics: bool,
|
||||
|
||||
/// Whether to check alignment during evaluation.
|
||||
check_alignment: bool,
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> {
|
||||
pub(crate) fn new(const_eval_limit: Limit, can_access_statics: bool) -> Self {
|
||||
pub(crate) fn new(
|
||||
const_eval_limit: Limit,
|
||||
can_access_statics: bool,
|
||||
check_alignment: bool,
|
||||
) -> Self {
|
||||
CompileTimeInterpreter {
|
||||
steps_remaining: const_eval_limit.0,
|
||||
stack: Vec::new(),
|
||||
can_access_statics,
|
||||
check_alignment,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -238,7 +246,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
||||
|
||||
#[inline(always)]
|
||||
fn enforce_alignment(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
|
||||
ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks
|
||||
ecx.machine.check_alignment
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
@ -13,7 +13,11 @@ pub fn might_permit_raw_init<'tcx>(
|
||||
let strict = tcx.sess.opts.unstable_opts.strict_init_checks;
|
||||
|
||||
if strict {
|
||||
let machine = CompileTimeInterpreter::new(Limit::new(0), false);
|
||||
let machine = CompileTimeInterpreter::new(
|
||||
Limit::new(0),
|
||||
/*can_access_statics:*/ false,
|
||||
/*check_alignment:*/ true,
|
||||
);
|
||||
|
||||
let mut cx = InterpCx::new(tcx, rustc_span::DUMMY_SP, ParamEnv::reveal_all(), machine);
|
||||
|
||||
|
20
src/test/ui/consts/extra-const-ub/issue-100771.rs
Normal file
20
src/test/ui/consts/extra-const-ub/issue-100771.rs
Normal file
@ -0,0 +1,20 @@
|
||||
// check-pass
|
||||
// compile-flags: -Zextra-const-ub-checks
|
||||
|
||||
#[derive(PartialEq, Eq, Copy, Clone)]
|
||||
#[repr(packed)]
|
||||
struct Foo {
|
||||
field: (i64, u32, u32, u32),
|
||||
}
|
||||
|
||||
const FOO: Foo = Foo {
|
||||
field: (5, 6, 7, 8),
|
||||
};
|
||||
|
||||
fn main() {
|
||||
match FOO {
|
||||
Foo { field: (5, 6, 7, 8) } => {},
|
||||
FOO => unreachable!(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user