]> git.lizzy.rs Git - rust.git/commitdiff
Improve return code propagation.
authorAaron Hill <aa1ronham@gmail.com>
Wed, 20 Nov 2019 17:43:10 +0000 (12:43 -0500)
committerAaron Hill <aa1ronham@gmail.com>
Wed, 20 Nov 2019 17:43:10 +0000 (12:43 -0500)
Don't explicitly exit if we reported an evaluation error

src/bin/miri.rs
src/eval.rs

index 481491ea722f87200cb005a22d1f1dfccf48fe78..9e95e4b0a466a6113fd6c04edb258741d7824a5b 100644 (file)
@@ -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();
index 3dad5a0d8c73e2fac9ec29848702e2f154b1d0f2..603c30feb9f46b79bd9e3a616e998b1753a1c3f1 100644 (file)
@@ -29,7 +29,10 @@ pub struct MiriConfig {
     pub seed: Option<u64>,
 }
 
-// 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<i64> {
     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;
         }
     }
 }