diff options
| author | The Miri Conjob Bot <miri@cron.bot> | 2023-08-31 05:40:49 +0000 |
|---|---|---|
| committer | The Miri Conjob Bot <miri@cron.bot> | 2023-08-31 05:40:49 +0000 |
| commit | 31d9ac14f52c88fbec16a12787e23a7f5ba671cf (patch) | |
| tree | 6a886a36309aecfd5d3712a24e51bc28f8197917 /src/tools/miri | |
| parent | 4b915b8a86df64e6758b6cc329d83d5fe635f21d (diff) | |
| parent | 8cbd2c847b682a3ce460a79fa7576ee2eb461a00 (diff) | |
| download | rust-31d9ac14f52c88fbec16a12787e23a7f5ba671cf.tar.gz rust-31d9ac14f52c88fbec16a12787e23a7f5ba671cf.zip | |
Merge from rustc
Diffstat (limited to 'src/tools/miri')
| -rw-r--r-- | src/tools/miri/src/diagnostics.rs | 67 | ||||
| -rw-r--r-- | src/tools/miri/src/helpers.rs | 23 | ||||
| -rw-r--r-- | src/tools/miri/tests/fail/type-too-large.rs | 2 | ||||
| -rw-r--r-- | src/tools/miri/tests/fail/unsized-local.stderr | 2 | ||||
| -rw-r--r-- | src/tools/miri/tests/pass/unsized.rs | 24 |
5 files changed, 64 insertions, 54 deletions
diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index f3285ccf917..75c6911bcbe 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -1,9 +1,8 @@ -use std::fmt; +use std::fmt::{self, Write}; use std::num::NonZeroU64; use log::trace; -use rustc_const_eval::ReportErrorExt; use rustc_errors::DiagnosticMessage; use rustc_span::{source_map::DUMMY_SP, SpanData, Symbol}; use rustc_target::abi::{Align, Size}; @@ -271,17 +270,20 @@ pub fn report_error<'tcx, 'mir>( }; (title, helps) } else { - #[rustfmt::skip] let title = match e.kind() { - UndefinedBehavior(UndefinedBehaviorInfo::ValidationError(e)) if matches!(e.kind, ValidationErrorKind::PointerAsInt { .. } | ValidationErrorKind::PartialPointer) => - bug!("This validation error should be impossible in Miri: {:?}", e.kind), + UndefinedBehavior(UndefinedBehaviorInfo::ValidationError(validation_err)) + if matches!(validation_err.kind, ValidationErrorKind::PointerAsInt { .. } | ValidationErrorKind::PartialPointer) => + { + ecx.handle_ice(); // print interpreter backtrace + bug!("This validation error should be impossible in Miri: {}", ecx.format_error(e)); + } UndefinedBehavior(_) => "Undefined Behavior", ResourceExhaustion(_) => "resource exhaustion", Unsupported( // We list only the ones that can actually happen. - UnsupportedOpInfo::Unsupported(_) + UnsupportedOpInfo::Unsupported(_) | UnsupportedOpInfo::UnsizedLocal ) => "unsupported operation", InvalidProgram( @@ -290,8 +292,10 @@ pub fn report_error<'tcx, 'mir>( InvalidProgramInfo::Layout(..) ) => "post-monomorphization error", - kind => - bug!("This error should be impossible in Miri: {kind:?}"), + _ => { + ecx.handle_ice(); // print interpreter backtrace + bug!("This error should be impossible in Miri: {}", ecx.format_error(e)); + } }; #[rustfmt::skip] let helps = match e.kind() { @@ -333,30 +337,22 @@ pub fn report_error<'tcx, 'mir>( let stacktrace = ecx.generate_stacktrace(); let (stacktrace, was_pruned) = prune_stacktrace(stacktrace, &ecx.machine); - let (e, backtrace) = e.into_parts(); - backtrace.print_backtrace(); - - // We want to dump the allocation if this is `InvalidUninitBytes`. Since `add_args` consumes - // the `InterpError`, we extract the variables it before that. - let extra = match e { - UndefinedBehavior(UndefinedBehaviorInfo::InvalidUninitBytes(Some((alloc_id, access)))) => - Some((alloc_id, access)), - _ => None, - }; - // FIXME(fee1-dead), HACK: we want to use the error as title therefore we can just extract the - // label and arguments from the InterpError. - let e = { - let handler = &ecx.tcx.sess.parse_sess.span_diagnostic; - let mut diag = ecx.tcx.sess.struct_allow(""); - let msg = e.diagnostic_message(); - e.add_args(handler, &mut diag); - let s = handler.eagerly_translate_to_string(msg, diag.args()); - diag.cancel(); - s - }; + // We want to dump the allocation if this is `InvalidUninitBytes`. Since `format_error` consumes `e`, we compute the outut early. + let mut extra = String::new(); + match e.kind() { + UndefinedBehavior(UndefinedBehaviorInfo::InvalidUninitBytes(Some((alloc_id, access)))) => { + writeln!( + extra, + "Uninitialized memory occurred at {alloc_id:?}{range:?}, in this allocation:", + range = access.bad, + ).unwrap(); + writeln!(extra, "{:?}", ecx.dump_alloc(*alloc_id)).unwrap(); + } + _ => {} + } - msg.insert(0, e); + msg.insert(0, ecx.format_error(e)); report_msg( DiagLevel::Error, @@ -375,6 +371,8 @@ pub fn report_error<'tcx, 'mir>( ); } + eprint!("{extra}"); // newlines are already in the string + // Debug-dump all locals. for (i, frame) in ecx.active_thread_stack().iter().enumerate() { trace!("-------------------"); @@ -385,15 +383,6 @@ pub fn report_error<'tcx, 'mir>( } } - // Extra output to help debug specific issues. - if let Some((alloc_id, access)) = extra { - eprintln!( - "Uninitialized memory occurred at {alloc_id:?}{range:?}, in this allocation:", - range = access.bad, - ); - eprintln!("{:?}", ecx.dump_alloc(alloc_id)); - } - None } diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index b5cc5c7e486..844827889a7 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -14,7 +14,7 @@ use rustc_middle::mir; use rustc_middle::ty::{ self, layout::{IntegerExt as _, LayoutOf, TyAndLayout}, - List, Ty, TyCtxt, + Ty, TyCtxt, }; use rustc_span::{def_id::CrateNum, sym, Span, Symbol}; use rustc_target::abi::{Align, FieldIdx, FieldsShape, Integer, Size, Variants}; @@ -282,13 +282,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { Ok(ptr.addr().bytes() == 0) } - /// Get the `Place` for a local - fn local_place(&self, local: mir::Local) -> InterpResult<'tcx, PlaceTy<'tcx, Provenance>> { - let this = self.eval_context_ref(); - let place = mir::Place { local, projection: List::empty() }; - this.eval_place(place) - } - /// Generate some random bytes, and write them to `dest`. fn gen_random(&mut self, ptr: Pointer<Option<Provenance>>, len: u64) -> InterpResult<'tcx> { // Some programs pass in a null pointer and a length of 0 @@ -350,17 +343,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Initialize arguments. let mut callee_args = this.frame().body.args_iter(); for arg in args { - let callee_arg = this.local_place( - callee_args - .next() - .ok_or_else(|| err_ub_format!("callee has fewer arguments than expected"))?, - )?; + let local = callee_args + .next() + .ok_or_else(|| err_ub_format!("callee has fewer arguments than expected"))?; + // Make the local live, and insert the initial value. + this.storage_live(local)?; + let callee_arg = this.local_to_place(this.frame_idx(), local)?; this.write_immediate(*arg, &callee_arg)?; } if callee_args.next().is_some() { throw_ub_format!("callee has more arguments than expected"); } + // Initialize remaining locals. + this.storage_live_for_always_live_locals()?; + Ok(()) } diff --git a/src/tools/miri/tests/fail/type-too-large.rs b/src/tools/miri/tests/fail/type-too-large.rs index 21b272f8ec3..81ecc6145d7 100644 --- a/src/tools/miri/tests/fail/type-too-large.rs +++ b/src/tools/miri/tests/fail/type-too-large.rs @@ -1,6 +1,6 @@ //@ignore-32bit fn main() { - let _fat: [u8; (1 << 61) + (1 << 31)]; + let _fat: [u8; (1 << 61) + (1 << 31)]; // ideally we'd error here, but we avoid computing the layout until absolutely necessary _fat = [0; (1u64 << 61) as usize + (1u64 << 31) as usize]; //~ ERROR: post-monomorphization error } diff --git a/src/tools/miri/tests/fail/unsized-local.stderr b/src/tools/miri/tests/fail/unsized-local.stderr index 66d93c6f503..07f94f3b91b 100644 --- a/src/tools/miri/tests/fail/unsized-local.stderr +++ b/src/tools/miri/tests/fail/unsized-local.stderr @@ -2,7 +2,7 @@ error: unsupported operation: unsized locals are not supported --> $DIR/unsized-local.rs:LL:CC | LL | let x = *(Box::new(A) as Box<dyn Foo>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsized locals are not supported + | ^ unsized locals are not supported | = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support = note: BACKTRACE: diff --git a/src/tools/miri/tests/pass/unsized.rs b/src/tools/miri/tests/pass/unsized.rs index c9046dc3c76..5c6929882f6 100644 --- a/src/tools/miri/tests/pass/unsized.rs +++ b/src/tools/miri/tests/pass/unsized.rs @@ -2,6 +2,7 @@ //@[tree]compile-flags: -Zmiri-tree-borrows #![feature(unsized_tuple_coercion)] #![feature(unsized_fn_params)] +#![feature(custom_mir, core_intrinsics)] use std::mem; @@ -32,7 +33,30 @@ fn unsized_params() { f3(*p); } +fn unsized_field_projection() { + use std::intrinsics::mir::*; + + pub struct S<T: ?Sized>(T); + + #[custom_mir(dialect = "runtime", phase = "optimized")] + fn f(x: S<[u8]>) { + mir! { + { + let idx = 0; + // Project to an unsized field of an unsized local. + x.0[idx] = 0; + let _val = x.0[idx]; + Return() + } + } + } + + let x: Box<S<[u8]>> = Box::new(S([0])); + f(*x); +} + fn main() { unsized_tuple(); unsized_params(); + unsized_field_projection(); } |
