Skip to content

Commit 3102129

Browse files
committed
Improve return code propagation.
Don't explicitly exit if we reported an evaluation error
1 parent 2532b86 commit 3102129

File tree

2 files changed

+19
-5
lines changed

2 files changed

+19
-5
lines changed

src/bin/miri.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ extern crate rustc_interface;
1515
extern crate syntax;
1616

1717
use std::str::FromStr;
18+
use std::convert::TryFrom;
1819
use std::env;
1920

2021
use hex::FromHexError;
@@ -39,7 +40,9 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
3940
// Add filename to `miri` arguments.
4041
config.args.insert(0, compiler.input().filestem().to_string());
4142

42-
miri::eval_main(tcx, entry_def_id, config);
43+
if let Some(return_code) = miri::eval_main(tcx, entry_def_id, config) {
44+
std::process::exit(i32::try_from(return_code).expect("Return value was too large!"));
45+
}
4346
});
4447

4548
compiler.session().abort_if_errors();

src/eval.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ pub struct MiriConfig {
2929
pub seed: Option<u64>,
3030
}
3131

32-
// Used by priroda.
32+
/// Returns a freshly created `InterpCx`, along with an `MPlaceTy` representing
33+
/// the location where the return value of the `start` lang item will be
34+
/// written to.
35+
/// Used by `priroda` and `miri
3336
pub fn create_ecx<'mir, 'tcx: 'mir>(
3437
tcx: TyCtxt<'tcx>,
3538
main_id: DefId,
@@ -173,7 +176,10 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
173176
Ok((ecx, ret_ptr))
174177
}
175178

176-
pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) {
179+
/// Evaluates the main function specified by `main_id`.
180+
/// Returns `Some(return_code)` if program executed completed.
181+
/// Returns `None` if an evaluation error occured
182+
pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) -> Option<i64> {
177183
let (mut ecx, ret_ptr) = match create_ecx(tcx, main_id, config) {
178184
Ok(v) => v,
179185
Err(mut err) => {
@@ -202,13 +208,16 @@ pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) {
202208
let ignore_leaks = target_os == "windows" || target_os == "macos";
203209
if !ignore_leaks && leaks != 0 {
204210
tcx.sess.err("the evaluated program leaked memory");
211+
// Ignore the provided return code - let the reported error
212+
// determine the return code
213+
return None;
205214
}
206-
std::process::exit(return_code as i32);
215+
return Some(return_code)
207216
}
208217
Err(mut e) => {
209218
// Special treatment for some error kinds
210219
let msg = match e.kind {
211-
InterpError::Exit(code) => std::process::exit(code),
220+
InterpError::Exit(code) => return Some(code.into()),
212221
err_unsup!(NoMirFor(..)) =>
213222
format!("{}. Did you set `MIRI_SYSROOT` to a Miri-enabled sysroot? You can prepare one with `cargo miri setup`.", e),
214223
_ => e.to_string()
@@ -251,6 +260,8 @@ pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) {
251260
trace!(" local {}: {:?}", i, local.value);
252261
}
253262
}
263+
// Let the reported error determine the return code
264+
return None;
254265
}
255266
}
256267
}

0 commit comments

Comments
 (0)