implement exit

implement exit code via new error kind
This commit is contained in:
Ralf Jung 2019-04-19 17:25:27 +02:00
parent 788616d0f0
commit 0694435650
4 changed files with 19 additions and 6 deletions

View File

@ -1 +1 @@
130dc3e7dac132cf30272ccf4541b512828e2108
9224be5fa39f6170f6e046342976efee5453a1ff

View File

@ -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),

View File

@ -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() {

3
tests/run-pass/exit.rs Normal file
View File

@ -0,0 +1,3 @@
fn main() {
std::process::exit(0)
}