Skip to content

Commit 4ace537

Browse files
committed
Auto merge of #114993 - RalfJung:panic-nounwind, r=fee1-dead
interpret/miri: call the panic_nounwind machinery the same way codegen does
2 parents 1303b7f + 708d20a commit 4ace537

19 files changed

+217
-58
lines changed

src/machine.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -971,9 +971,22 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
971971
ecx.assert_panic(msg, unwind)
972972
}
973973

974-
#[inline(always)]
975-
fn abort(_ecx: &mut MiriInterpCx<'mir, 'tcx>, msg: String) -> InterpResult<'tcx, !> {
976-
throw_machine_stop!(TerminationInfo::Abort(msg))
974+
fn panic_nounwind(ecx: &mut InterpCx<'mir, 'tcx, Self>, msg: &str) -> InterpResult<'tcx> {
975+
ecx.start_panic_nounwind(msg)
976+
}
977+
978+
fn unwind_terminate(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
979+
// Call the lang item.
980+
let panic = ecx.tcx.lang_items().panic_cannot_unwind().unwrap();
981+
let panic = ty::Instance::mono(ecx.tcx.tcx, panic);
982+
ecx.call_function(
983+
panic,
984+
Abi::Rust,
985+
&[],
986+
None,
987+
StackPopCleanup::Goto { ret: None, unwind: mir::UnwindAction::Unreachable },
988+
)?;
989+
Ok(())
977990
}
978991

979992
#[inline(always)]

src/shims/intrinsics/mod.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,20 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
3434
if this.emulate_intrinsic(instance, args, dest, ret)? {
3535
return Ok(());
3636
}
37-
38-
// All remaining supported intrinsics have a return place.
3937
let intrinsic_name = this.tcx.item_name(instance.def_id());
4038
let intrinsic_name = intrinsic_name.as_str();
39+
40+
// Handle intrinsics without return place.
41+
match intrinsic_name {
42+
"abort" => {
43+
throw_machine_stop!(TerminationInfo::Abort(
44+
"the program aborted execution".to_owned()
45+
))
46+
}
47+
_ => {},
48+
}
49+
50+
// All remaining supported intrinsics have a return place.
4151
let ret = match ret {
4252
None => throw_unsup_format!("unimplemented (diverging) intrinsic: `{intrinsic_name}`"),
4353
Some(p) => p,
@@ -393,7 +403,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
393403
"breakpoint" => {
394404
let [] = check_arg_count(args)?;
395405
// normally this would raise a SIGTRAP, which aborts if no debugger is connected
396-
throw_machine_stop!(TerminationInfo::Abort(format!("Trace/breakpoint trap")))
406+
throw_machine_stop!(TerminationInfo::Abort(format!("trace/breakpoint trap")))
397407
}
398408

399409
name => throw_unsup_format!("unimplemented intrinsic: `{name}`"),

src/shims/panic.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,25 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
188188
)
189189
}
190190

191+
/// Start a non-unwinding panic in the interpreter with the given message as payload.
192+
fn start_panic_nounwind(&mut self, msg: &str) -> InterpResult<'tcx> {
193+
let this = self.eval_context_mut();
194+
195+
// First arg: message.
196+
let msg = this.allocate_str(msg, MiriMemoryKind::Machine.into(), Mutability::Not)?;
197+
198+
// Call the lang item.
199+
let panic = this.tcx.lang_items().panic_nounwind().unwrap();
200+
let panic = ty::Instance::mono(this.tcx.tcx, panic);
201+
this.call_function(
202+
panic,
203+
Abi::Rust,
204+
&[msg.to_ref(this)],
205+
None,
206+
StackPopCleanup::Goto { ret: None, unwind: mir::UnwindAction::Unreachable },
207+
)
208+
}
209+
191210
fn assert_panic(
192211
&mut self,
193212
msg: &mir::AssertMessage<'tcx>,

tests/fail/breakpoint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
fn main() {
44
unsafe {
5-
core::intrinsics::breakpoint() //~ ERROR: Trace/breakpoint trap
5+
core::intrinsics::breakpoint() //~ ERROR: trace/breakpoint trap
66
};
77
}

tests/fail/breakpoint.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error: abnormal termination: Trace/breakpoint trap
1+
error: abnormal termination: trace/breakpoint trap
22
--> $DIR/breakpoint.rs:LL:CC
33
|
44
LL | core::intrinsics::breakpoint()
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Trace/breakpoint trap
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trace/breakpoint trap
66
|
77
= note: inside `main` at $DIR/breakpoint.rs:LL:CC
88

tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,35 @@
11
thread 'main' panicked at $DIR/exported_symbol_bad_unwind2.rs:LL:CC:
22
explicit panic
33
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
4-
error: abnormal termination: panic in a function that cannot unwind
4+
thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
5+
panic in a function that cannot unwind
6+
stack backtrace:
7+
thread caused non-unwinding panic. aborting.
8+
error: abnormal termination: the program aborted execution
9+
--> RUSTLIB/std/src/sys/PLATFORM/mod.rs:LL:CC
10+
|
11+
LL | ABORT();
12+
| ^ the program aborted execution
13+
|
14+
= note: inside `std::sys::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/PLATFORM/mod.rs:LL:CC
15+
= note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
16+
= note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
17+
= note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::panicking::begin_panic_handler::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
18+
= note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
19+
= note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC
20+
= note: inside `core::panicking::panic_cannot_unwind` at RUSTLIB/core/src/panicking.rs:LL:CC
21+
note: inside `nounwind`
522
--> $DIR/exported_symbol_bad_unwind2.rs:LL:CC
623
|
724
LL | / extern "C-unwind" fn nounwind() {
8-
LL | |
9-
LL | |
1025
LL | | panic!();
1126
LL | | }
12-
| |_^ panic in a function that cannot unwind
13-
|
14-
= note: inside `nounwind` at $DIR/exported_symbol_bad_unwind2.rs:LL:CC
27+
| |_^
1528
note: inside `main`
1629
--> $DIR/exported_symbol_bad_unwind2.rs:LL:CC
1730
|
1831
LL | unsafe { nounwind() }
19-
| ^^^^^^^^^^
32+
| ^
2033

2134
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
2235

tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,35 @@
11
thread 'main' panicked at $DIR/exported_symbol_bad_unwind2.rs:LL:CC:
22
explicit panic
33
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
4-
error: abnormal termination: panic in a function that cannot unwind
4+
thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
5+
panic in a function that cannot unwind
6+
stack backtrace:
7+
thread caused non-unwinding panic. aborting.
8+
error: abnormal termination: the program aborted execution
9+
--> RUSTLIB/std/src/sys/PLATFORM/mod.rs:LL:CC
10+
|
11+
LL | ABORT();
12+
| ^ the program aborted execution
13+
|
14+
= note: inside `std::sys::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/PLATFORM/mod.rs:LL:CC
15+
= note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
16+
= note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
17+
= note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::panicking::begin_panic_handler::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
18+
= note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
19+
= note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC
20+
= note: inside `core::panicking::panic_cannot_unwind` at RUSTLIB/core/src/panicking.rs:LL:CC
21+
note: inside `nounwind`
522
--> $DIR/exported_symbol_bad_unwind2.rs:LL:CC
623
|
724
LL | / extern "C-unwind" fn nounwind() {
8-
LL | |
9-
LL | |
1025
LL | | panic!();
1126
LL | | }
12-
| |_^ panic in a function that cannot unwind
13-
|
14-
= note: inside `nounwind` at $DIR/exported_symbol_bad_unwind2.rs:LL:CC
27+
| |_^
1528
note: inside `main`
1629
--> $DIR/exported_symbol_bad_unwind2.rs:LL:CC
1730
|
1831
LL | unsafe { nounwind() }
19-
| ^^^^^^^^^^
32+
| ^
2033

2134
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
2235

tests/fail/function_calls/exported_symbol_bad_unwind2.extern_block.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ error: Undefined Behavior: unwinding past a stack frame that does not allow unwi
55
--> $DIR/exported_symbol_bad_unwind2.rs:LL:CC
66
|
77
LL | unsafe { nounwind() }
8-
| ^^^^^^^^^^ unwinding past a stack frame that does not allow unwinding
8+
| ^ unwinding past a stack frame that does not allow unwinding
99
|
1010
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
1111
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information

tests/fail/function_calls/exported_symbol_bad_unwind2.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
//@revisions: extern_block definition both
2+
//@normalize-stderr-test: "unsafe \{ libc::abort\(\) \}|crate::intrinsics::abort\(\);" -> "ABORT();"
3+
//@normalize-stderr-test: "\| +\^+" -> "| ^"
4+
//@normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> "$1"
5+
//@normalize-stderr-test: "\n at [^\n]+" -> "$1"
6+
//@[definition,both]error-in-other-file: aborted execution
27
#![feature(rustc_attrs, c_unwind)]
38

49
#[cfg_attr(any(definition, both), rustc_nounwind)]
510
#[no_mangle]
611
extern "C-unwind" fn nounwind() {
7-
//~[definition]^ ERROR: abnormal termination: panic in a function that cannot unwind
8-
//~[both]^^ ERROR: abnormal termination: panic in a function that cannot unwind
912
panic!();
1013
}
1114

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
//@normalize-stderr-test: "unsafe \{ libc::abort\(\) \}|crate::intrinsics::abort\(\);" -> "ABORT();"
2+
//@normalize-stderr-test: "\| +\^+" -> "| ^"
3+
//@normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> "$1"
4+
//@normalize-stderr-test: "\n at [^\n]+" -> "$1"
5+
//@error-in-other-file: aborted execution
16
#![feature(never_type)]
27

38
#[allow(deprecated, invalid_value)]
49
fn main() {
510
let _ = unsafe { std::mem::uninitialized::<!>() };
6-
//~^ ERROR: attempted to instantiate uninhabited type `!`
711
}

tests/fail/intrinsics/uninit_uninhabited_type.stderr

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,24 @@
1-
error: abnormal termination: aborted execution: attempted to instantiate uninhabited type `!`
1+
thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
2+
aborted execution: attempted to instantiate uninhabited type `!`
3+
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
4+
thread caused non-unwinding panic. aborting.
5+
error: abnormal termination: the program aborted execution
6+
--> RUSTLIB/std/src/sys/PLATFORM/mod.rs:LL:CC
7+
|
8+
LL | ABORT();
9+
| ^ the program aborted execution
10+
|
11+
= note: inside `std::sys::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/PLATFORM/mod.rs:LL:CC
12+
= note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
13+
= note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
14+
= note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::panicking::begin_panic_handler::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
15+
= note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
16+
= note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC
17+
note: inside `main`
218
--> $DIR/uninit_uninhabited_type.rs:LL:CC
319
|
420
LL | let _ = unsafe { std::mem::uninitialized::<!>() };
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to instantiate uninhabited type `!`
6-
|
7-
= note: inside `main` at $DIR/uninit_uninhabited_type.rs:LL:CC
21+
| ^
822

923
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
1024

tests/fail/intrinsics/zero_fn_ptr.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
//@normalize-stderr-test: "unsafe \{ libc::abort\(\) \}|crate::intrinsics::abort\(\);" -> "ABORT();"
2+
//@normalize-stderr-test: "\| +\^+" -> "| ^"
3+
//@normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> "$1"
4+
//@normalize-stderr-test: "\n at [^\n]+" -> "$1"
5+
//@error-in-other-file: aborted execution
6+
17
#[allow(deprecated, invalid_value)]
28
fn main() {
39
let _ = unsafe { std::mem::zeroed::<fn()>() };
4-
//~^ ERROR: attempted to zero-initialize type `fn()`, which is invalid
510
}

tests/fail/intrinsics/zero_fn_ptr.stderr

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,24 @@
1-
error: abnormal termination: aborted execution: attempted to zero-initialize type `fn()`, which is invalid
1+
thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
2+
aborted execution: attempted to zero-initialize type `fn()`, which is invalid
3+
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
4+
thread caused non-unwinding panic. aborting.
5+
error: abnormal termination: the program aborted execution
6+
--> RUSTLIB/std/src/sys/PLATFORM/mod.rs:LL:CC
7+
|
8+
LL | ABORT();
9+
| ^ the program aborted execution
10+
|
11+
= note: inside `std::sys::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/PLATFORM/mod.rs:LL:CC
12+
= note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
13+
= note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
14+
= note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::panicking::begin_panic_handler::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
15+
= note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
16+
= note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC
17+
note: inside `main`
218
--> $DIR/zero_fn_ptr.rs:LL:CC
319
|
420
LL | let _ = unsafe { std::mem::zeroed::<fn()>() };
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to zero-initialize type `fn()`, which is invalid
6-
|
7-
= note: inside `main` at $DIR/zero_fn_ptr.rs:LL:CC
21+
| ^
822

923
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
1024

tests/fail/panic/double_panic.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
//@normalize-stderr-test: "unsafe \{ libc::abort\(\) \}|crate::intrinsics::abort\(\);" -> "ABORT();"
12
//@normalize-stderr-test: "\| +\^+" -> "| ^"
23
//@normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> "$1"
34
//@normalize-stderr-test: "\n at [^\n]+" -> "$1"
5+
//@error-in-other-file: aborted execution
46

57
struct Foo;
68
impl Drop for Foo {
@@ -9,7 +11,6 @@ impl Drop for Foo {
911
}
1012
}
1113
fn main() {
12-
//~^ERROR: panic in a function that cannot unwind
1314
let _foo = Foo;
1415
panic!("first");
1516
}

tests/fail/panic/double_panic.stderr

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,31 @@ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
44
thread 'main' panicked at $DIR/double_panic.rs:LL:CC:
55
second
66
stack backtrace:
7-
error: abnormal termination: panic in a function that cannot unwind
7+
thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
8+
panic in a function that cannot unwind
9+
stack backtrace:
10+
thread caused non-unwinding panic. aborting.
11+
error: abnormal termination: the program aborted execution
12+
--> RUSTLIB/std/src/sys/PLATFORM/mod.rs:LL:CC
13+
|
14+
LL | ABORT();
15+
| ^ the program aborted execution
16+
|
17+
= note: inside `std::sys::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/PLATFORM/mod.rs:LL:CC
18+
= note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
19+
= note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
20+
= note: inside `std::sys_common::backtrace::__rust_end_short_backtrace::<[closure@std::panicking::begin_panic_handler::{closure#0}], !>` at RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC
21+
= note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
22+
= note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC
23+
= note: inside `core::panicking::panic_cannot_unwind` at RUSTLIB/core/src/panicking.rs:LL:CC
24+
note: inside `main`
825
--> $DIR/double_panic.rs:LL:CC
926
|
1027
LL | / fn main() {
11-
LL | |
1228
LL | | let _foo = Foo;
1329
LL | | panic!("first");
1430
LL | | }
15-
| |_^ panic in a function that cannot unwind
16-
|
17-
= note: inside `main` at $DIR/double_panic.rs:LL:CC
31+
| |_^
1832

1933
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
2034

tests/fail/terminate-terminator.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
//@compile-flags: -Zmir-opt-level=3 -Zinline-mir-hint-threshold=1000
2-
// Enable MIR inlining to ensure that `TerminatorKind::Terminate` is generated
2+
//@normalize-stderr-test: "unsafe \{ libc::abort\(\) \}|crate::intrinsics::abort\(\);" -> "ABORT();"
3+
//@normalize-stderr-test: "\| +\^+" -> "| ^"
4+
//@normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> "$1"
5+
//@normalize-stderr-test: "\n at [^\n]+" -> "$1"
6+
//@error-in-other-file: aborted execution
7+
// Enable MIR inlining to ensure that `TerminatorKind::UnwindTerminate` is generated
38
// instead of just `UnwindAction::Terminate`.
49

510
#![feature(c_unwind)]
@@ -12,7 +17,6 @@ impl Drop for Foo {
1217

1318
#[inline(always)]
1419
fn has_cleanup() {
15-
//~^ ERROR: panic in a function that cannot unwind
1620
let _f = Foo;
1721
panic!();
1822
}

0 commit comments

Comments
 (0)