From 0f1713f67cb66b2af3fd84c34a58b92f0a0c99bf Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 19 Mar 2020 15:50:02 +0100 Subject: [PATCH 1/2] whitelist platforms where panicking should work --- src/shims/foreign_items.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/shims/foreign_items.rs b/src/shims/foreign_items.rs index fab90e3cc5..af2c6d6ebb 100644 --- a/src/shims/foreign_items.rs +++ b/src/shims/foreign_items.rs @@ -132,6 +132,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx // This matches calls to the foreign item `panic_impl`. // The implementation is provided by the function with the `#[panic_handler]` attribute. "panic_impl" => { + // Make sure panicking actually works on this platform. + match this.tcx.sess.target.target.target_os.as_str() { + "linux" | "macos" => {}, + _ => throw_unsup_format!("panicking is not supported on this platform"), + } + let panic_impl_id = this.tcx.lang_items().panic_impl().unwrap(); let panic_impl_instance = ty::Instance::mono(*this.tcx, panic_impl_id); return Ok(Some(&*this.load_mir(panic_impl_instance.def, None)?)); From bde3111c61a325a2ddaf7b47975ee2758b30e969 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 21 Mar 2020 10:16:47 +0100 Subject: [PATCH 2/2] test windows panic message --- src/shims/foreign_items.rs | 7 +------ src/shims/mod.rs | 8 ++++++++ src/shims/panic.rs | 8 ++++++++ tests/compile-fail/panic/windows1.rs | 9 +++++++++ tests/compile-fail/panic/windows2.rs | 9 +++++++++ tests/compile-fail/panic/windows3.rs | 10 ++++++++++ 6 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 tests/compile-fail/panic/windows1.rs create mode 100644 tests/compile-fail/panic/windows2.rs create mode 100644 tests/compile-fail/panic/windows3.rs diff --git a/src/shims/foreign_items.rs b/src/shims/foreign_items.rs index af2c6d6ebb..60da1f1e6c 100644 --- a/src/shims/foreign_items.rs +++ b/src/shims/foreign_items.rs @@ -132,12 +132,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx // This matches calls to the foreign item `panic_impl`. // The implementation is provided by the function with the `#[panic_handler]` attribute. "panic_impl" => { - // Make sure panicking actually works on this platform. - match this.tcx.sess.target.target.target_os.as_str() { - "linux" | "macos" => {}, - _ => throw_unsup_format!("panicking is not supported on this platform"), - } - + this.check_panic_supported()?; let panic_impl_id = this.tcx.lang_items().panic_impl().unwrap(); let panic_impl_instance = ty::Instance::mono(*this.tcx, panic_impl_id); return Ok(Some(&*this.load_mir(panic_impl_instance.def, None)?)); diff --git a/src/shims/mod.rs b/src/shims/mod.rs index d9e4d226ec..5b5a11b86b 100644 --- a/src/shims/mod.rs +++ b/src/shims/mod.rs @@ -42,6 +42,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx return this.emulate_foreign_item(instance.def_id(), args, ret, unwind); } + // Better error message for panics on Windows. + let def_id = instance.def_id(); + if Some(def_id) == this.tcx.lang_items().begin_panic_fn() || + Some(def_id) == this.tcx.lang_items().panic_impl() + { + this.check_panic_supported()?; + } + // Otherwise, load the MIR. Ok(Some(&*this.load_mir(instance.def, None)?)) } diff --git a/src/shims/panic.rs b/src/shims/panic.rs index 2f61ab6c39..8dded8bf40 100644 --- a/src/shims/panic.rs +++ b/src/shims/panic.rs @@ -32,6 +32,14 @@ pub struct CatchUnwindData<'tcx> { impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {} pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> { + /// Check if panicking is supported on this platform, and give a good error otherwise. + fn check_panic_supported(&self) -> InterpResult<'tcx> { + match self.eval_context_ref().tcx.sess.target.target.target_os.as_str() { + "linux" | "macos" => Ok(()), + _ => throw_unsup_format!("panicking is not supported on this platform"), + } + } + /// Handles the special `miri_start_panic` intrinsic, which is called /// by libpanic_unwind to delegate the actual unwinding process to Miri. fn handle_miri_start_panic( diff --git a/tests/compile-fail/panic/windows1.rs b/tests/compile-fail/panic/windows1.rs new file mode 100644 index 0000000000..1d6faf1e75 --- /dev/null +++ b/tests/compile-fail/panic/windows1.rs @@ -0,0 +1,9 @@ +// ignore-linux +// ignore-macos + +// Test that panics on Windows give a reasonable error message. + +// error-pattern: panicking is not supported on this platform +fn main() { + core::panic!("this is {}", "Windows"); +} diff --git a/tests/compile-fail/panic/windows2.rs b/tests/compile-fail/panic/windows2.rs new file mode 100644 index 0000000000..023088a692 --- /dev/null +++ b/tests/compile-fail/panic/windows2.rs @@ -0,0 +1,9 @@ +// ignore-linux +// ignore-macos + +// Test that panics on Windows give a reasonable error message. + +// error-pattern: panicking is not supported on this platform +fn main() { + std::panic!("this is Windows"); +} diff --git a/tests/compile-fail/panic/windows3.rs b/tests/compile-fail/panic/windows3.rs new file mode 100644 index 0000000000..b96022fc4e --- /dev/null +++ b/tests/compile-fail/panic/windows3.rs @@ -0,0 +1,10 @@ +// ignore-linux +// ignore-macos + +// Test that panics on Windows give a reasonable error message. + +// error-pattern: panicking is not supported on this platform +#[allow(unconditional_panic)] +fn main() { + let _val = 1/0; +}