Skip to content

Commit 066eb08

Browse files
authored
Rollup merge of #71950 - RalfJung:try-validation-cleanup, r=oli-obk
Miri validation error handling cleanup Slightly expand @jumbatm's pattern macro and use it throughout validation. This ensures we never incorrectly swallow `InvalidProgram` errors or ICE when they occur. Fixes #71353 r? @oli-obk
2 parents d33180e + 0e2a712 commit 066eb08

File tree

6 files changed

+205
-174
lines changed

6 files changed

+205
-174
lines changed

src/librustc_middle/mir/interpret/error.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ use super::{AllocId, Pointer, RawConst, ScalarMaybeUndef};
33
use crate::mir::interpret::ConstValue;
44
use crate::ty::layout::LayoutError;
55
use crate::ty::query::TyCtxtAt;
6-
use crate::ty::tls;
7-
use crate::ty::{self, layout, Ty};
6+
use crate::ty::{self, layout, tls, FnSig, Ty};
87

98
use rustc_data_structures::sync::Lock;
109
use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorReported};
@@ -329,7 +328,7 @@ impl fmt::Display for CheckInAllocMsg {
329328
}
330329

331330
/// Error information for when the program caused Undefined Behavior.
332-
pub enum UndefinedBehaviorInfo {
331+
pub enum UndefinedBehaviorInfo<'tcx> {
333332
/// Free-form case. Only for errors that are never caught!
334333
Ub(String),
335334
/// Unreachable code was executed.
@@ -347,6 +346,8 @@ pub enum UndefinedBehaviorInfo {
347346
PointerArithOverflow,
348347
/// Invalid metadata in a wide pointer (using `str` to avoid allocations).
349348
InvalidMeta(&'static str),
349+
/// Invalid drop function in vtable.
350+
InvalidDropFn(FnSig<'tcx>),
350351
/// Reading a C string that does not end within its allocation.
351352
UnterminatedCString(Pointer),
352353
/// Dereferencing a dangling pointer after it got freed.
@@ -380,6 +381,8 @@ pub enum UndefinedBehaviorInfo {
380381
InvalidDiscriminant(ScalarMaybeUndef),
381382
/// Using a pointer-not-to-a-function as function pointer.
382383
InvalidFunctionPointer(Pointer),
384+
/// Using a string that is not valid UTF-8,
385+
InvalidStr(std::str::Utf8Error),
383386
/// Using uninitialized data where it is not allowed.
384387
InvalidUndefBytes(Option<Pointer>),
385388
/// Working with a local that is not currently live.
@@ -391,7 +394,7 @@ pub enum UndefinedBehaviorInfo {
391394
},
392395
}
393396

394-
impl fmt::Display for UndefinedBehaviorInfo {
397+
impl fmt::Display for UndefinedBehaviorInfo<'_> {
395398
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
396399
use UndefinedBehaviorInfo::*;
397400
match self {
@@ -404,6 +407,11 @@ impl fmt::Display for UndefinedBehaviorInfo {
404407
RemainderByZero => write!(f, "calculating the remainder with a divisor of zero"),
405408
PointerArithOverflow => write!(f, "overflowing in-bounds pointer arithmetic"),
406409
InvalidMeta(msg) => write!(f, "invalid metadata in wide pointer: {}", msg),
410+
InvalidDropFn(sig) => write!(
411+
f,
412+
"invalid drop function signature: got {}, expected exactly one argument which must be a pointer type",
413+
sig
414+
),
407415
UnterminatedCString(p) => write!(
408416
f,
409417
"reading a null-terminated string starting at {} with no null found before end of allocation",
@@ -446,6 +454,7 @@ impl fmt::Display for UndefinedBehaviorInfo {
446454
InvalidFunctionPointer(p) => {
447455
write!(f, "using {} as function pointer but it does not point to a function", p)
448456
}
457+
InvalidStr(err) => write!(f, "this string is not valid UTF-8: {}", err),
449458
InvalidUndefBytes(Some(p)) => write!(
450459
f,
451460
"reading uninitialized memory at {}, but this operation requires initialized memory",
@@ -549,7 +558,7 @@ impl dyn MachineStopType {
549558

550559
pub enum InterpError<'tcx> {
551560
/// The program caused undefined behavior.
552-
UndefinedBehavior(UndefinedBehaviorInfo),
561+
UndefinedBehavior(UndefinedBehaviorInfo<'tcx>),
553562
/// The program did something the interpreter does not support (some of these *might* be UB
554563
/// but the interpreter is not sure).
555564
Unsupported(UnsupportedOpInfo),

src/librustc_mir/interpret/operand.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
327327
pub fn read_str(&self, mplace: MPlaceTy<'tcx, M::PointerTag>) -> InterpResult<'tcx, &str> {
328328
let len = mplace.len(self)?;
329329
let bytes = self.memory.read_bytes(mplace.ptr, Size::from_bytes(len))?;
330-
let str = ::std::str::from_utf8(bytes)
331-
.map_err(|err| err_ub_format!("this string is not valid UTF-8: {}", err))?;
330+
let str = ::std::str::from_utf8(bytes).map_err(|err| err_ub!(InvalidStr(err)))?;
332331
Ok(str)
333332
}
334333

src/librustc_mir/interpret/traits.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -147,14 +147,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
147147
// The drop function takes `*mut T` where `T` is the type being dropped, so get that.
148148
let args = fn_sig.inputs();
149149
if args.len() != 1 {
150-
throw_ub_format!("drop fn should have 1 argument, but signature is {:?}", fn_sig);
150+
throw_ub!(InvalidDropFn(fn_sig));
151151
}
152-
let ty = args[0]
153-
.builtin_deref(true)
154-
.ok_or_else(|| {
155-
err_ub_format!("drop fn argument type {} is not a pointer type", args[0])
156-
})?
157-
.ty;
152+
let ty = args[0].builtin_deref(true).ok_or_else(|| err_ub!(InvalidDropFn(fn_sig)))?.ty;
158153
Ok((drop_instance, ty))
159154
}
160155

0 commit comments

Comments
 (0)