mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 14:01:51 +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
|
/// 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
|
/// 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
|
/// 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,
|
tcx,
|
||||||
root_span,
|
root_span,
|
||||||
param_env,
|
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 cid = key.value;
|
||||||
let def_id = cid.instance.def.def_id();
|
let def_id = cid.instance.def.def_id();
|
||||||
let is_static = tcx.is_static(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(
|
let mplace = ecx.raw_const_to_mplace(constant).expect(
|
||||||
"can only fail if layout computation failed, \
|
"can only fail if layout computation failed, \
|
||||||
@ -300,7 +310,11 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
|
|||||||
key.param_env,
|
key.param_env,
|
||||||
// Statics (and promoteds inside statics) may access other statics, because unlike consts
|
// 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.
|
// 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);
|
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.
|
/// * Pointers to allocations inside of statics can never leak outside, to a non-static global.
|
||||||
/// This boolean here controls the second part.
|
/// This boolean here controls the second part.
|
||||||
pub(super) can_access_statics: bool,
|
pub(super) can_access_statics: bool,
|
||||||
|
|
||||||
|
/// Whether to check alignment during evaluation.
|
||||||
|
check_alignment: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> {
|
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 {
|
CompileTimeInterpreter {
|
||||||
steps_remaining: const_eval_limit.0,
|
steps_remaining: const_eval_limit.0,
|
||||||
stack: Vec::new(),
|
stack: Vec::new(),
|
||||||
can_access_statics,
|
can_access_statics,
|
||||||
|
check_alignment,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -238,7 +246,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn enforce_alignment(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
|
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)]
|
#[inline(always)]
|
||||||
|
@ -13,7 +13,11 @@ pub fn might_permit_raw_init<'tcx>(
|
|||||||
let strict = tcx.sess.opts.unstable_opts.strict_init_checks;
|
let strict = tcx.sess.opts.unstable_opts.strict_init_checks;
|
||||||
|
|
||||||
if strict {
|
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);
|
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