From 310212931666421636286d223ca88841b26011c2 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 20 Nov 2019 12:43:10 -0500 Subject: [PATCH] Improve return code propagation. Don't explicitly exit if we reported an evaluation error --- src/bin/miri.rs | 5 ++++- src/eval.rs | 19 +++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/bin/miri.rs b/src/bin/miri.rs index 481491ea722..9e95e4b0a46 100644 --- a/src/bin/miri.rs +++ b/src/bin/miri.rs @@ -15,6 +15,7 @@ extern crate syntax; use std::str::FromStr; +use std::convert::TryFrom; use std::env; use hex::FromHexError; @@ -39,7 +40,9 @@ fn after_analysis(&mut self, compiler: &interface::Compiler) -> Compilation { // Add filename to `miri` arguments. config.args.insert(0, compiler.input().filestem().to_string()); - miri::eval_main(tcx, entry_def_id, config); + if let Some(return_code) = miri::eval_main(tcx, entry_def_id, config) { + std::process::exit(i32::try_from(return_code).expect("Return value was too large!")); + } }); compiler.session().abort_if_errors(); diff --git a/src/eval.rs b/src/eval.rs index 3dad5a0d8c7..603c30feb9f 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -29,7 +29,10 @@ pub struct MiriConfig { pub seed: Option, } -// Used by priroda. +/// Returns a freshly created `InterpCx`, along with an `MPlaceTy` representing +/// the location where the return value of the `start` lang item will be +/// written to. +/// Used by `priroda` and `miri pub fn create_ecx<'mir, 'tcx: 'mir>( tcx: TyCtxt<'tcx>, main_id: DefId, @@ -173,7 +176,10 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( Ok((ecx, ret_ptr)) } -pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) { +/// Evaluates the main function specified by `main_id`. +/// Returns `Some(return_code)` if program executed completed. +/// Returns `None` if an evaluation error occured +pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) -> Option { let (mut ecx, ret_ptr) = match create_ecx(tcx, main_id, config) { Ok(v) => v, Err(mut err) => { @@ -202,13 +208,16 @@ pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) { let ignore_leaks = target_os == "windows" || target_os == "macos"; if !ignore_leaks && leaks != 0 { tcx.sess.err("the evaluated program leaked memory"); + // Ignore the provided return code - let the reported error + // determine the return code + return None; } - std::process::exit(return_code as i32); + return Some(return_code) } Err(mut e) => { // Special treatment for some error kinds let msg = match e.kind { - InterpError::Exit(code) => std::process::exit(code), + InterpError::Exit(code) => return Some(code.into()), err_unsup!(NoMirFor(..)) => format!("{}. Did you set `MIRI_SYSROOT` to a Miri-enabled sysroot? You can prepare one with `cargo miri setup`.", e), _ => e.to_string() @@ -251,6 +260,8 @@ pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) { trace!(" local {}: {:?}", i, local.value); } } + // Let the reported error determine the return code + return None; } } } -- 2.44.0