From 0694435650adbd5965a30a14771bc142919bbfe4 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 19 Apr 2019 17:25:27 +0200 Subject: [PATCH 1/4] implement exit implement exit code via new error kind --- rust-version | 2 +- src/fn_call.rs | 6 +++++- src/lib.rs | 14 ++++++++++---- tests/run-pass/exit.rs | 3 +++ 4 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 tests/run-pass/exit.rs 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 ae6aff10ac2..2f827510aa5 100644 --- a/src/fn_call.rs +++ b/src/fn_call.rs @@ -69,11 +69,15 @@ 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" => { + 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/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) +} From d410b131395ee0ba0cc02d6ca8cedc04e7c1fded Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 21 Apr 2019 13:18:05 +0200 Subject: [PATCH 2/4] fix compile-fail ref files --- tests/compile-fail/ctlz_nonzero.rs | 2 +- tests/compile-fail/cttz_nonzero.rs | 2 +- tests/compile-fail/deref_fn_ptr.rs | 2 +- tests/compile-fail/getrandom.rs | 2 +- tests/compile-fail/never_transmute_humans.rs | 3 +-- tests/compile-fail/null_pointer_deref.rs | 2 +- tests/compile-fail/null_pointer_deref_zst.rs | 2 +- tests/compile-fail/null_pointer_write.rs | 2 +- tests/compile-fail/null_pointer_write_zst.rs | 2 +- 9 files changed, 9 insertions(+), 10 deletions(-) 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 } From 6a6c0cd5f0f2e7283f2271f2188280e5ce9b9e69 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 21 Apr 2019 13:25:24 +0200 Subject: [PATCH 3/4] implement ExitProcess for Windows --- src/fn_call.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/fn_call.rs b/src/fn_call.rs index 2f827510aa5..84033e9e830 100644 --- a/src/fn_call.rs +++ b/src/fn_call.rs @@ -78,6 +78,10 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<' let code = this.read_scalar(args[0])?.to_i32()?; return err!(Exit(code)); } + "ExitProcess" => { + let code = this.read_scalar(args[0])?.to_u32()?; + return err!(Exit(code as i32)); + } _ => if dest.is_none() { return err!(Unimplemented( format!("can't call diverging foreign function: {}", link_name), From aaa8ee743bca78d52018a025a525183405b2a1b1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 22 Apr 2019 13:20:51 +0200 Subject: [PATCH 4/4] unify code paths --- src/fn_call.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/fn_call.rs b/src/fn_call.rs index 62ad675218a..29a34a69686 100644 --- a/src/fn_call.rs +++ b/src/fn_call.rs @@ -154,14 +154,11 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<' "__rust_start_panic" | "panic_impl" => { return err!(MachineError("the evaluated program panicked".to_string())); } - "exit" => { + "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)); } - "ExitProcess" => { - let code = this.read_scalar(args[0])?.to_u32()?; - return err!(Exit(code as i32)); - } _ => if dest.is_none() { return err!(Unimplemented( format!("can't call diverging foreign function: {}", link_name),