From 48ac35f0727e1c660fa95012a941cf65de8b9443 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 6 Feb 2019 11:39:16 +0100 Subject: [PATCH] panic_impl is another way to panic --- src/fn_call.rs | 30 +++++++++++++--------- tests/compile-fail/{panic.rs => panic1.rs} | 2 +- tests/compile-fail/panic2.rs | 5 ++++ tests/compile-fail/panic3.rs | 5 ++++ tests/compile-fail/panic4.rs | 5 ++++ 5 files changed, 34 insertions(+), 13 deletions(-) rename tests/compile-fail/{panic.rs => panic1.rs} (60%) create mode 100644 tests/compile-fail/panic2.rs create mode 100644 tests/compile-fail/panic3.rs create mode 100644 tests/compile-fail/panic4.rs diff --git a/src/fn_call.rs b/src/fn_call.rs index 720737b5396..abb239ad7d6 100644 --- a/src/fn_call.rs +++ b/src/fn_call.rs @@ -39,12 +39,7 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a, if this.tcx.is_foreign_item(instance.def_id()) { // An external function that we cannot find MIR for, but we can still run enough // of them to make miri viable. - this.emulate_foreign_item( - instance.def_id(), - args, - dest.unwrap(), - ret.unwrap(), - )?; + this.emulate_foreign_item(instance.def_id(), args, dest, ret)?; // `goto_block` already handled return Ok(None); } @@ -59,8 +54,8 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a, &mut self, def_id: DefId, args: &[OpTy<'tcx, Borrow>], - dest: PlaceTy<'tcx, Borrow>, - ret: mir::BasicBlock, + dest: Option>, + ret: Option, ) -> EvalResult<'tcx> { let this = self.eval_context_mut(); let attrs = this.tcx.get_attrs(def_id); @@ -70,9 +65,23 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a, }; // Strip linker suffixes (seen on 32bit macOS) let link_name = link_name.trim_end_matches("$UNIX2003"); - let tcx = &{this.tcx.tcx}; + // first: functions that could diverge + match &link_name[..] { + "__rust_start_panic" | "panic_impl" => { + return err!(MachineError("the evaluated program panicked".to_string())); + } + _ => if dest.is_none() { + return err!(Unimplemented( + format!("can't call diverging foreign function: {}", link_name), + )); + } + } + + // now: functions that assume a ret and dest + let dest = dest.expect("we already checked for a dest"); + let ret = ret.expect("dest is Some but ret is None"); match &link_name[..] { "malloc" => { let size = this.read_scalar(args[0])?.to_usize(this)?; @@ -245,9 +254,6 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a, return Ok(()); } - "__rust_start_panic" => - return err!(MachineError("the evaluated program panicked".to_string())), - "memcmp" => { let left = this.read_scalar(args[0])?.not_undef()?; let right = this.read_scalar(args[1])?.not_undef()?; diff --git a/tests/compile-fail/panic.rs b/tests/compile-fail/panic1.rs similarity index 60% rename from tests/compile-fail/panic.rs rename to tests/compile-fail/panic1.rs index 0d594f9bd4c..1163c870828 100644 --- a/tests/compile-fail/panic.rs +++ b/tests/compile-fail/panic1.rs @@ -1,5 +1,5 @@ //error-pattern: the evaluated program panicked fn main() { - assert_eq!(5, 6); + std::panic!("panicking from libstd"); } diff --git a/tests/compile-fail/panic2.rs b/tests/compile-fail/panic2.rs new file mode 100644 index 00000000000..e643e692241 --- /dev/null +++ b/tests/compile-fail/panic2.rs @@ -0,0 +1,5 @@ +//error-pattern: the evaluated program panicked + +fn main() { + std::panic!("{}-panicking from libstd", 42); +} diff --git a/tests/compile-fail/panic3.rs b/tests/compile-fail/panic3.rs new file mode 100644 index 00000000000..b22f95d9c69 --- /dev/null +++ b/tests/compile-fail/panic3.rs @@ -0,0 +1,5 @@ +//error-pattern: the evaluated program panicked + +fn main() { + core::panic!("panicking from libcore"); +} diff --git a/tests/compile-fail/panic4.rs b/tests/compile-fail/panic4.rs new file mode 100644 index 00000000000..449e716e161 --- /dev/null +++ b/tests/compile-fail/panic4.rs @@ -0,0 +1,5 @@ +//error-pattern: the evaluated program panicked + +fn main() { + core::panic!("{}-panicking from libcore", 42); +}