diff --git a/rust-version b/rust-version index f0c4e551b3a..fae9b1d599a 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -130dc3e7dac132cf30272ccf4541b512828e2108 +9224be5fa39f6170f6e046342976efee5453a1ff diff --git a/src/fn_call.rs b/src/fn_call.rs index 7a684bdaa78..29a34a69686 100644 --- a/src/fn_call.rs +++ b/src/fn_call.rs @@ -149,11 +149,16 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<' let link_name = link_name.get().trim_end_matches("$UNIX2003"); let tcx = &{this.tcx.tcx}; - // First: functions that could diverge. + // First: functions that diverge. match link_name { "__rust_start_panic" | "panic_impl" => { return err!(MachineError("the evaluated program panicked".to_string())); } + "exit" | "ExitProcess" => { + // it's really u32 for ExitProcess, but we have to put it into the `Exit` error variant anyway + let code = this.read_scalar(args[0])?.to_i32()?; + return err!(Exit(code)); + } _ => if dest.is_none() { return err!(Unimplemented( format!("can't call diverging foreign function: {}", link_name), diff --git a/src/lib.rs b/src/lib.rs index 3dbe922999d..683eee0cb7a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -242,6 +242,13 @@ pub fn eval_main<'a, 'tcx: 'a>( } } Err(mut e) => { + // Special treatment for some error kinds + let msg = match e.kind { + InterpError::Exit(code) => std::process::exit(code), + InterpError::NoMirFor(..) => + format!("{}. Did you set `MIRI_SYSROOT` to a Miri-enabled sysroot? You can prepare one with `cargo miri setup`.", e), + _ => e.to_string() + }; e.print_backtrace(); if let Some(frame) = ecx.stack().last() { let block = &frame.mir.basic_blocks()[frame.block]; @@ -251,11 +258,10 @@ pub fn eval_main<'a, 'tcx: 'a>( block.terminator().source_info.span }; - let e = e.to_string(); - let msg = format!("constant evaluation error: {}", e); + let msg = format!("Miri evaluation error: {}", msg); let mut err = struct_error(ecx.tcx.tcx.at(span), msg.as_str()); let frames = ecx.generate_stacktrace(None); - err.span_label(span, e); + err.span_label(span, msg); // We iterate with indices because we need to look at the next frame (the caller). for idx in 0..frames.len() { let frame_info = &frames[idx]; @@ -269,7 +275,7 @@ pub fn eval_main<'a, 'tcx: 'a>( } err.emit(); } else { - ecx.tcx.sess.err(&e.to_string()); + ecx.tcx.sess.err(&msg); } for (i, frame) in ecx.stack().iter().enumerate() { diff --git a/tests/compile-fail/ctlz_nonzero.rs b/tests/compile-fail/ctlz_nonzero.rs index 86fd5ec46c2..61f41363589 100644 --- a/tests/compile-fail/ctlz_nonzero.rs +++ b/tests/compile-fail/ctlz_nonzero.rs @@ -10,6 +10,6 @@ pub fn main() { unsafe { use crate::rusti::*; - ctlz_nonzero(0u8); //~ ERROR constant evaluation error: ctlz_nonzero called on 0 + ctlz_nonzero(0u8); //~ ERROR ctlz_nonzero called on 0 } } diff --git a/tests/compile-fail/cttz_nonzero.rs b/tests/compile-fail/cttz_nonzero.rs index a6c3b03cfb5..69d2874ce92 100644 --- a/tests/compile-fail/cttz_nonzero.rs +++ b/tests/compile-fail/cttz_nonzero.rs @@ -10,6 +10,6 @@ pub fn main() { unsafe { use crate::rusti::*; - cttz_nonzero(0u8); //~ ERROR constant evaluation error: cttz_nonzero called on 0 + cttz_nonzero(0u8); //~ ERROR cttz_nonzero called on 0 } } diff --git a/tests/compile-fail/deref_fn_ptr.rs b/tests/compile-fail/deref_fn_ptr.rs index 68826a6ff03..ed2ac60f43f 100644 --- a/tests/compile-fail/deref_fn_ptr.rs +++ b/tests/compile-fail/deref_fn_ptr.rs @@ -2,7 +2,7 @@ fn f() {} fn main() { let x: u8 = unsafe { - *std::mem::transmute::(f) //~ ERROR constant evaluation error: tried to dereference a function pointer + *std::mem::transmute::(f) //~ ERROR tried to dereference a function pointer }; panic!("this should never print: {}", x); } diff --git a/tests/compile-fail/getrandom.rs b/tests/compile-fail/getrandom.rs index d54c95c8238..246893a5c64 100644 --- a/tests/compile-fail/getrandom.rs +++ b/tests/compile-fail/getrandom.rs @@ -8,6 +8,6 @@ fn main() { let mut buf = [0u8; 5]; unsafe { libc::syscall(libc::SYS_getrandom, buf.as_mut_ptr() as *mut libc::c_void, 5 as libc::size_t, 0 as libc::c_uint); - //~^ ERROR constant evaluation error: miri does not support gathering system entropy in deterministic mode! + //~^ ERROR miri does not support gathering system entropy in deterministic mode! } } diff --git a/tests/compile-fail/never_transmute_humans.rs b/tests/compile-fail/never_transmute_humans.rs index 34203338696..ab25b1ffc74 100644 --- a/tests/compile-fail/never_transmute_humans.rs +++ b/tests/compile-fail/never_transmute_humans.rs @@ -7,7 +7,6 @@ struct Human; fn main() { let _x: ! = unsafe { - std::mem::transmute::(Human) //~ ERROR constant evaluation error - //^~ NOTE entered unreachable code + std::mem::transmute::(Human) //~ ERROR entered unreachable code }; } diff --git a/tests/compile-fail/null_pointer_deref.rs b/tests/compile-fail/null_pointer_deref.rs index 08ea63f58ff..8bf0392b890 100644 --- a/tests/compile-fail/null_pointer_deref.rs +++ b/tests/compile-fail/null_pointer_deref.rs @@ -1,4 +1,4 @@ fn main() { - let x: i32 = unsafe { *std::ptr::null() }; //~ ERROR constant evaluation error: invalid use of NULL pointer + let x: i32 = unsafe { *std::ptr::null() }; //~ ERROR invalid use of NULL pointer panic!("this should never print: {}", x); } diff --git a/tests/compile-fail/null_pointer_deref_zst.rs b/tests/compile-fail/null_pointer_deref_zst.rs index a8b23368616..b2800e96292 100644 --- a/tests/compile-fail/null_pointer_deref_zst.rs +++ b/tests/compile-fail/null_pointer_deref_zst.rs @@ -1,4 +1,4 @@ fn main() { - let x: () = unsafe { *std::ptr::null() }; //~ ERROR constant evaluation error: invalid use of NULL pointer + let x: () = unsafe { *std::ptr::null() }; //~ ERROR invalid use of NULL pointer panic!("this should never print: {:?}", x); } diff --git a/tests/compile-fail/null_pointer_write.rs b/tests/compile-fail/null_pointer_write.rs index affb040bded..1577b2a1b13 100644 --- a/tests/compile-fail/null_pointer_write.rs +++ b/tests/compile-fail/null_pointer_write.rs @@ -1,3 +1,3 @@ fn main() { - unsafe { *std::ptr::null_mut() = 0i32 }; //~ ERROR constant evaluation error: invalid use of NULL pointer + unsafe { *std::ptr::null_mut() = 0i32 }; //~ ERROR invalid use of NULL pointer } diff --git a/tests/compile-fail/null_pointer_write_zst.rs b/tests/compile-fail/null_pointer_write_zst.rs index 433c69dbb03..7e91d736bd2 100644 --- a/tests/compile-fail/null_pointer_write_zst.rs +++ b/tests/compile-fail/null_pointer_write_zst.rs @@ -2,5 +2,5 @@ fn main() { // Not using the () type here, as writes of that type do not even have MIR generated. // Also not assigning directly as that's array initialization, not assignment. let zst_val = [1u8; 0]; - unsafe { *std::ptr::null_mut() = zst_val }; //~ ERROR constant evaluation error: invalid use of NULL pointer + unsafe { *std::ptr::null_mut() = zst_val }; //~ ERROR invalid use of NULL pointer } diff --git a/tests/run-pass/exit.rs b/tests/run-pass/exit.rs new file mode 100644 index 00000000000..d93f0045377 --- /dev/null +++ b/tests/run-pass/exit.rs @@ -0,0 +1,3 @@ +fn main() { + std::process::exit(0) +}