Skip to content

Commit d8a1454

Browse files
committed
miri: Detect uninitialized integers and floats
Change the Miri engine to allow configuring whether to check initialization of integers and floats. This allows the Miri tool to optionally check for initialization if requested by the user.
1 parent 00d5e42 commit d8a1454

File tree

2 files changed

+12
-5
lines changed

2 files changed

+12
-5
lines changed

compiler/rustc_const_eval/src/interpret/machine.rs

+9
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ pub trait Machine<'mir, 'tcx>: Sized {
131131
/// Whether to enforce the validity invariant
132132
fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
133133

134+
/// Whether to enforce validity (e.g., initialization and not having ptr provenance)
135+
/// of integers and floats.
136+
fn enforce_number_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
137+
134138
/// Whether function calls should be [ABI](Abi)-checked.
135139
fn enforce_abi(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
136140
true
@@ -426,6 +430,11 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
426430
false // for now, we don't enforce validity
427431
}
428432

433+
#[inline(always)]
434+
fn enforce_number_validity(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
435+
true
436+
}
437+
429438
#[inline(always)]
430439
fn call_extra_fn(
431440
_ecx: &mut InterpCx<$mir, $tcx, Self>,

compiler/rustc_const_eval/src/interpret/validity.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -520,17 +520,14 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
520520
let value = self.read_scalar(value)?;
521521
// NOTE: Keep this in sync with the array optimization for int/float
522522
// types below!
523-
if self.ctfe_mode.is_some() {
523+
if M::enforce_number_validity(self.ecx) {
524524
// Integers/floats in CTFE: Must be scalar bits, pointers are dangerous
525525
let is_bits = value.check_init().map_or(false, |v| v.try_to_int().is_ok());
526526
if !is_bits {
527527
throw_validation_failure!(self.path,
528528
{ "{}", value } expected { "initialized plain (non-pointer) bytes" }
529529
)
530530
}
531-
} else {
532-
// At run-time, for now, we accept *anything* for these types, including
533-
// uninit. We should fix that, but let's start low.
534531
}
535532
Ok(true)
536533
}
@@ -855,9 +852,10 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
855852
}
856853
};
857854

855+
let allow_uninit_and_ptr = !M::enforce_number_validity(self.ecx);
858856
match alloc.check_bytes(
859857
alloc_range(Size::ZERO, size),
860-
/*allow_uninit_and_ptr*/ self.ctfe_mode.is_none(),
858+
allow_uninit_and_ptr,
861859
) {
862860
// In the happy case, we needn't check anything else.
863861
Ok(()) => {}

0 commit comments

Comments
 (0)