mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-17 06:26:55 +00:00
Update Miri for detecting uninitialized numbers
This commit adds a `-Zmiri-check-number-initialization` flag to check that integers and floats are initialized. This commit also changes some shims to write at type `MaybeUninit<...>` in order to prevent spurious errors from the uninit check.
This commit is contained in:
parent
3f2c9ee17e
commit
e6a9b2ce68
@ -313,6 +313,9 @@ fn main() {
|
||||
"-Zmiri-symbolic-alignment-check" => {
|
||||
miri_config.check_alignment = miri::AlignmentCheck::Symbolic;
|
||||
}
|
||||
"-Zmiri-check-number-validity" => {
|
||||
miri_config.check_number_validity = true;
|
||||
}
|
||||
"-Zmiri-disable-abi-check" => {
|
||||
miri_config.check_abi = false;
|
||||
}
|
||||
|
@ -66,6 +66,8 @@ pub struct MiriConfig {
|
||||
pub stacked_borrows: bool,
|
||||
/// Controls alignment checking.
|
||||
pub check_alignment: AlignmentCheck,
|
||||
/// Controls integer and float validity (e.g., initialization) checking.
|
||||
pub check_number_validity: bool,
|
||||
/// Controls function [ABI](Abi) checking.
|
||||
pub check_abi: bool,
|
||||
/// Action for an op requiring communication with the host.
|
||||
@ -104,6 +106,7 @@ impl Default for MiriConfig {
|
||||
validate: true,
|
||||
stacked_borrows: true,
|
||||
check_alignment: AlignmentCheck::Int,
|
||||
check_number_validity: false,
|
||||
check_abi: true,
|
||||
isolated_op: IsolatedOp::Reject(RejectOpWith::Abort),
|
||||
ignore_leaks: false,
|
||||
|
@ -304,6 +304,9 @@ pub struct Evaluator<'mir, 'tcx> {
|
||||
/// Whether to enforce the validity invariant.
|
||||
pub(crate) validate: bool,
|
||||
|
||||
/// Whether to enforce validity (e.g., initialization) of integers and floats.
|
||||
pub(crate) enforce_number_validity: bool,
|
||||
|
||||
/// Whether to enforce [ABI](Abi) of function calls.
|
||||
pub(crate) enforce_abi: bool,
|
||||
|
||||
@ -356,6 +359,7 @@ impl<'mir, 'tcx> Evaluator<'mir, 'tcx> {
|
||||
tls: TlsData::default(),
|
||||
isolated_op: config.isolated_op,
|
||||
validate: config.validate,
|
||||
enforce_number_validity: config.check_number_validity,
|
||||
enforce_abi: config.check_abi,
|
||||
file_handler: Default::default(),
|
||||
dir_handler: Default::default(),
|
||||
@ -426,6 +430,11 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> {
|
||||
ecx.machine.validate
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn enforce_number_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
|
||||
ecx.machine.enforce_number_validity
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn enforce_abi(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
|
||||
ecx.machine.enforce_abi
|
||||
|
@ -1,5 +1,8 @@
|
||||
use std::time::SystemTime;
|
||||
|
||||
use rustc_hir::LangItem;
|
||||
use rustc_middle::ty::{layout::TyAndLayout, query::TyCtxtAt, subst::Subst, Ty};
|
||||
|
||||
use crate::*;
|
||||
use thread::Time;
|
||||
|
||||
@ -44,7 +47,7 @@ fn mutexattr_set_kind<'mir, 'tcx: 'mir>(
|
||||
attr_op: &OpTy<'tcx, Tag>,
|
||||
kind: impl Into<ScalarMaybeUninit<Tag>>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
ecx.write_scalar_at_offset(attr_op, 0, kind, ecx.machine.layouts.i32)
|
||||
ecx.write_scalar_at_offset(attr_op, 0, kind, layout_of_maybe_uninit(ecx.tcx, ecx.tcx.types.i32))
|
||||
}
|
||||
|
||||
// pthread_mutex_t is between 24 and 48 bytes, depending on the platform.
|
||||
@ -79,7 +82,7 @@ fn mutex_set_kind<'mir, 'tcx: 'mir>(
|
||||
mutex_op,
|
||||
offset,
|
||||
kind,
|
||||
ecx.machine.layouts.i32,
|
||||
layout_of_maybe_uninit(ecx.tcx, ecx.tcx.types.i32),
|
||||
AtomicWriteOp::Relaxed,
|
||||
)
|
||||
}
|
||||
@ -100,7 +103,7 @@ fn mutex_set_id<'mir, 'tcx: 'mir>(
|
||||
mutex_op,
|
||||
4,
|
||||
id,
|
||||
ecx.machine.layouts.u32,
|
||||
layout_of_maybe_uninit(ecx.tcx, ecx.tcx.types.u32),
|
||||
AtomicWriteOp::Relaxed,
|
||||
)
|
||||
}
|
||||
@ -144,7 +147,7 @@ fn rwlock_set_id<'mir, 'tcx: 'mir>(
|
||||
rwlock_op,
|
||||
4,
|
||||
id,
|
||||
ecx.machine.layouts.u32,
|
||||
layout_of_maybe_uninit(ecx.tcx, ecx.tcx.types.u32),
|
||||
AtomicWriteOp::Relaxed,
|
||||
)
|
||||
}
|
||||
@ -211,7 +214,7 @@ fn cond_set_id<'mir, 'tcx: 'mir>(
|
||||
cond_op,
|
||||
4,
|
||||
id,
|
||||
ecx.machine.layouts.u32,
|
||||
layout_of_maybe_uninit(ecx.tcx, ecx.tcx.types.u32),
|
||||
AtomicWriteOp::Relaxed,
|
||||
)
|
||||
}
|
||||
@ -244,7 +247,12 @@ fn cond_set_clock_id<'mir, 'tcx: 'mir>(
|
||||
cond_op: &OpTy<'tcx, Tag>,
|
||||
clock_id: impl Into<ScalarMaybeUninit<Tag>>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
ecx.write_scalar_at_offset(cond_op, 8, clock_id, ecx.machine.layouts.i32)
|
||||
ecx.write_scalar_at_offset(
|
||||
cond_op,
|
||||
8,
|
||||
clock_id,
|
||||
layout_of_maybe_uninit(ecx.tcx, ecx.tcx.types.i32),
|
||||
)
|
||||
}
|
||||
|
||||
/// Try to reacquire the mutex associated with the condition variable after we
|
||||
@ -788,3 +796,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
|
||||
fn layout_of_maybe_uninit<'tcx>(tcx: TyCtxtAt<'tcx>, param: Ty<'tcx>) -> TyAndLayout<'tcx> {
|
||||
let def_id = tcx.require_lang_item(LangItem::MaybeUninit, None);
|
||||
let def_ty = tcx.type_of(def_id);
|
||||
let ty = def_ty.subst(*tcx, &[param.into()]);
|
||||
|
||||
let param_env = tcx.param_env(def_id);
|
||||
tcx.layout_of(param_env.and(ty)).unwrap()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user