diff --git a/src/diagnostics.rs b/src/diagnostics.rs index fb6598495a..b2590a843b 100644 --- a/src/diagnostics.rs +++ b/src/diagnostics.rs @@ -20,7 +20,8 @@ pub fn report_diagnostic<'tcx, 'mir>( let info = info.downcast_ref::().expect("invalid MachineStop payload"); match info { TerminationInfo::Exit(code) => return Some(*code), - TerminationInfo::Abort => format!("the evaluated program aborted execution"), + TerminationInfo::Abort(None) => format!("the evaluated program aborted execution"), + TerminationInfo::Abort(Some(msg)) => format!("the evaluated program aborted execution: {}", msg), } } err_unsup!(NoMirFor(..)) => format!( diff --git a/src/eval.rs b/src/eval.rs index 2cf5a1dc44..7d42db6894 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -53,7 +53,7 @@ impl Default for MiriConfig { /// Details of premature program termination. pub enum TerminationInfo { Exit(i64), - Abort, + Abort(Option), } /// Returns a freshly created `InterpCx`, along with an `MPlaceTy` representing diff --git a/src/machine.rs b/src/machine.rs index d94c6928cf..3a8e7fc902 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -273,7 +273,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> { #[inline(always)] fn abort(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx, !> { - throw_machine_stop!(TerminationInfo::Abort) + throw_machine_stop!(TerminationInfo::Abort(None)) } #[inline(always)] diff --git a/src/shims/intrinsics.rs b/src/shims/intrinsics.rs index b91af778d9..112b4f3c00 100644 --- a/src/shims/intrinsics.rs +++ b/src/shims/intrinsics.rs @@ -440,15 +440,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx "assert_uninit_valid" => { let ty = substs.type_at(0); let layout = this.layout_of(ty)?; - // Return here because we panicked instead of returning normally from the intrinsic. + // Abort here because the caller might not be panic safe. if layout.abi.is_uninhabited() { - return this.start_panic(&format!("attempted to instantiate uninhabited type `{}`", ty), unwind); + throw_machine_stop!(TerminationInfo::Abort(Some(format!("attempted to instantiate uninhabited type `{}`", ty)))) } if intrinsic_name == "assert_zero_valid" && !layout.might_permit_raw_init(this, /*zero:*/ true).unwrap() { - return this.start_panic(&format!("attempted to zero-initialize type `{}`, which is invalid", ty), unwind); + throw_machine_stop!(TerminationInfo::Abort(Some(format!("attempted to zero-initialize type `{}`, which is invalid", ty)))) } if intrinsic_name == "assert_uninit_valid" && !layout.might_permit_raw_init(this, /*zero:*/ false).unwrap() { - return this.start_panic(&format!("attempted to leave type `{}` uninitialized, which is invalid", ty), unwind); + throw_machine_stop!(TerminationInfo::Abort(Some(format!("attempted to leave type `{}` uninitialized, which is invalid", ty)))) } } diff --git a/tests/compile-fail/invalid_zero_init.rs b/tests/compile-fail/invalid_zero_init.rs new file mode 100644 index 0000000000..78c2b0fbee --- /dev/null +++ b/tests/compile-fail/invalid_zero_init.rs @@ -0,0 +1,6 @@ + // error-pattern: the evaluated program aborted execution: attempted to zero-initialize type `fn()`, which is invalid + +#[allow(deprecated, invalid_value)] +fn main() { + unsafe { std::mem::zeroed::() }; +} diff --git a/tests/compile-fail/uninit_uninhabited_type.rs b/tests/compile-fail/uninit_uninhabited_type.rs new file mode 100644 index 0000000000..b904883078 --- /dev/null +++ b/tests/compile-fail/uninit_uninhabited_type.rs @@ -0,0 +1,7 @@ + // error-pattern: the evaluated program aborted execution: attempted to instantiate uninhabited type `!` +#![feature(never_type)] + +#[allow(deprecated, invalid_value)] +fn main() { + unsafe { std::mem::uninitialized::() }; +} diff --git a/tests/run-pass/panic/catch_panic.rs b/tests/run-pass/panic/catch_panic.rs index cc97ba5a85..6408c940d9 100644 --- a/tests/run-pass/panic/catch_panic.rs +++ b/tests/run-pass/panic/catch_panic.rs @@ -67,43 +67,6 @@ fn main() { |_old_val| { let _val = 1/0; loop {} }, ); - // libcore panics from shims. - #[allow(deprecated, invalid_value)] - { - test( - Some("attempted to instantiate uninhabited type `!`"), - |_old_val| unsafe { std::mem::uninitialized::() }, - ); - test( - Some("attempted to instantiate uninhabited type `!`"), - |_old_val| unsafe { std::mem::zeroed::() }, - ); - test( - Some("attempted to leave type `fn()` uninitialized, which is invalid"), - |_old_val| unsafe { std::mem::uninitialized::(); loop {} }, - ); - test( - Some("attempted to zero-initialize type `fn()`, which is invalid"), - |_old_val| unsafe { std::mem::zeroed::(); loop {} }, - ); - test( - Some("attempted to leave type `*const dyn std::marker::Sync` uninitialized, which is invalid"), - |_old_val| unsafe { std::mem::uninitialized::<*const dyn Sync>(); loop {} }, - ); - test( - Some("attempted to zero-initialize type `*mut dyn std::marker::Sync`, which is invalid"), - |_old_val| unsafe { std::mem::zeroed::<*mut dyn Sync>(); loop {} }, - ); - test( - Some("attempted to leave type `&u8` uninitialized, which is invalid"), - |_old_val| unsafe { std::mem::uninitialized::<&u8>(); loop {} }, - ); - test( - Some("attempted to zero-initialize type `&u8`, which is invalid"), - |_old_val| unsafe { std::mem::zeroed::<&u8>(); loop {} }, - ); - } - test( Some("align_offset: align is not a power-of-two"), |_old_val| { (0usize as *const u8).align_offset(3); loop {} }, diff --git a/tests/run-pass/panic/catch_panic.stderr b/tests/run-pass/panic/catch_panic.stderr index 8d97fd6321..6da9cd2996 100644 --- a/tests/run-pass/panic/catch_panic.stderr +++ b/tests/run-pass/panic/catch_panic.stderr @@ -16,27 +16,11 @@ thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 4' Caught panic message (String): index out of bounds: the len is 3 but the index is 4 thread 'main' panicked at 'attempt to divide by zero', $DIR/catch_panic.rs:67:33 Caught panic message (String): attempt to divide by zero -thread 'main' panicked at 'attempted to instantiate uninhabited type `!`', $LOC -Caught panic message (String): attempted to instantiate uninhabited type `!` -thread 'main' panicked at 'attempted to instantiate uninhabited type `!`', $LOC -Caught panic message (String): attempted to instantiate uninhabited type `!` -thread 'main' panicked at 'attempted to leave type `fn()` uninitialized, which is invalid', $LOC -Caught panic message (String): attempted to leave type `fn()` uninitialized, which is invalid -thread 'main' panicked at 'attempted to zero-initialize type `fn()`, which is invalid', $LOC -Caught panic message (String): attempted to zero-initialize type `fn()`, which is invalid -thread 'main' panicked at 'attempted to leave type `*const dyn std::marker::Sync` uninitialized, which is invalid', $LOC -Caught panic message (String): attempted to leave type `*const dyn std::marker::Sync` uninitialized, which is invalid -thread 'main' panicked at 'attempted to zero-initialize type `*mut dyn std::marker::Sync`, which is invalid', $LOC -Caught panic message (String): attempted to zero-initialize type `*mut dyn std::marker::Sync`, which is invalid -thread 'main' panicked at 'attempted to leave type `&u8` uninitialized, which is invalid', $LOC -Caught panic message (String): attempted to leave type `&u8` uninitialized, which is invalid -thread 'main' panicked at 'attempted to zero-initialize type `&u8`, which is invalid', $LOC -Caught panic message (String): attempted to zero-initialize type `&u8`, which is invalid thread 'main' panicked at 'align_offset: align is not a power-of-two', $LOC Caught panic message (String): align_offset: align is not a power-of-two -thread 'main' panicked at 'assertion failed: false', $DIR/catch_panic.rs:113:29 +thread 'main' panicked at 'assertion failed: false', $DIR/catch_panic.rs:76:29 Caught panic message (&str): assertion failed: false -thread 'main' panicked at 'assertion failed: false', $DIR/catch_panic.rs:114:29 +thread 'main' panicked at 'assertion failed: false', $DIR/catch_panic.rs:77:29 Caught panic message (&str): assertion failed: false thread 'main' panicked at 'attempt to copy from unaligned or null pointer', $LOC Caught panic message (String): attempt to copy from unaligned or null pointer