Rollup merge of #100229 - RalfJung:extra-const-ub-checks, r=lcnr

add -Zextra-const-ub-checks to enable more UB checking in const-eval

Cc https://github.com/rust-lang/rust/issues/99923
r? `@oli-obk`
This commit is contained in:
Dylan DPC
2022-08-12 20:39:11 +05:30
committed by GitHub
8 changed files with 145 additions and 12 deletions

View File

@@ -236,6 +236,16 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
const PANIC_ON_ALLOC_FAIL: bool = false; // will be raised as a proper error
#[inline(always)]
fn enforce_alignment(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks
}
#[inline(always)]
fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks
}
fn load_mir(
ecx: &InterpCx<'mir, 'tcx, Self>,
instance: ty::InstanceDef<'tcx>,

View File

@@ -436,24 +436,12 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
type AllocExtra = ();
type FrameExtra = ();
#[inline(always)]
fn enforce_alignment(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
// We do not check for alignment to avoid having to carry an `Align`
// in `ConstValue::ByRef`.
false
}
#[inline(always)]
fn force_int_for_alignment_check(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
// We do not support `force_int`.
false
}
#[inline(always)]
fn enforce_validity(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
false // for now, we don't enforce validity
}
#[inline(always)]
fn enforce_number_init(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
true

View File

@@ -1005,6 +1005,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// It will error if the bits at the destination do not match the ones described by the layout.
#[inline(always)]
pub fn validate_operand(&self, op: &OpTy<'tcx, M::Provenance>) -> InterpResult<'tcx> {
// Note that we *could* actually be in CTFE here with `-Zextra-const-ub-checks`, but it's
// still correct to not use `ctfe_mode`: that mode is for validation of the final constant
// value, it rules out things like `UnsafeCell` in awkward places. It also can make checking
// recurse through references which, for now, we don't want here, either.
self.validate_operand_internal(op, vec![], None, None)
}
}

View File

@@ -183,6 +183,18 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
type MemoryKind = !;
#[inline(always)]
fn enforce_alignment(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
// We do not check for alignment to avoid having to carry an `Align`
// in `ConstValue::ByRef`.
false
}
#[inline(always)]
fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
false // for now, we don't enforce validity
}
fn load_mir(
_ecx: &InterpCx<'mir, 'tcx, Self>,
_instance: ty::InstanceDef<'tcx>,

View File

@@ -1310,6 +1310,8 @@ options! {
"emit the bc module with thin LTO info (default: yes)"),
export_executable_symbols: bool = (false, parse_bool, [TRACKED],
"export symbols from executables, as if they were dynamic libraries"),
extra_const_ub_checks: bool = (false, parse_bool, [TRACKED],
"turns on more checks to detect const UB, which can be slow (default: no)"),
#[cfg_attr(not(bootstrap), rustc_lint_opt_deny_field_access("use `Session::fewer_names` instead of this field"))]
fewer_names: Option<bool> = (None, parse_opt_bool, [TRACKED],
"reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \