Skip to content

Commit 788fd44

Browse files
committed
interpret/miri: call panic_cannot_unwind lang item instead of hard-coding the same message
1 parent 818ec8e commit 788fd44

14 files changed

+147
-42
lines changed

compiler/rustc_const_eval/src/interpret/eval_context.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
765765
}
766766
mir::UnwindAction::Terminate => {
767767
self.frame_mut().loc = Right(self.frame_mut().body.span);
768-
M::abort(self, "panic in a function that cannot unwind".to_owned())?;
768+
M::unwind_terminate(self)?;
769+
// This might have pushed a new stack frame, or it terminated execution.
770+
// Either way, `loc` will not be updated.
771+
return Ok(());
769772
}
770773
};
771774
Ok(())
@@ -865,6 +868,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
865868
panic!("encountered StackPopCleanup::Root when unwinding!")
866869
}
867870
};
871+
// This must be the very last thing that happens, since it can in fact push a new stack frame.
868872
self.unwind_to_block(unwind)
869873
} else {
870874
// Follow the normal return edge.

compiler/rustc_const_eval/src/interpret/machine.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,9 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
223223
throw_unsup_format!("aborting execution is not supported")
224224
}
225225

226+
/// Called when unwinding reached a state where execution should be terminated.
227+
fn unwind_terminate(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx>;
228+
226229
/// Called for all binary operations where the LHS has pointer type.
227230
///
228231
/// Returns a (value, overflowed) pair if the operation succeeded
@@ -499,6 +502,11 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
499502
false
500503
}
501504

505+
#[inline(always)]
506+
fn unwind_terminate(_ecx: &mut InterpCx<$mir, $tcx, Self>) -> InterpResult<$tcx> {
507+
unreachable!("unwinding cannot happen during compile-time evaluation")
508+
}
509+
502510
#[inline(always)]
503511
fn call_extra_fn(
504512
_ecx: &mut InterpCx<$mir, $tcx, Self>,

compiler/rustc_const_eval/src/interpret/terminator.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
197197
}
198198

199199
UnwindTerminate => {
200-
// FIXME: maybe should call `panic_no_unwind` lang item instead.
201-
M::abort(self, "panic in a function that cannot unwind".to_owned())?;
200+
M::unwind_terminate(self)?;
202201
}
203202

204203
// When we encounter Resume, we've finished unwinding

src/tools/miri/src/machine.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,20 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
976976
throw_machine_stop!(TerminationInfo::Abort(msg))
977977
}
978978

979+
fn unwind_terminate(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
980+
// Call the lang item.
981+
let panic = ecx.tcx.lang_items().panic_cannot_unwind().unwrap();
982+
let panic = ty::Instance::mono(ecx.tcx.tcx, panic);
983+
ecx.call_function(
984+
panic,
985+
Abi::Rust,
986+
&[],
987+
None,
988+
StackPopCleanup::Goto { ret: None, unwind: mir::UnwindAction::Unreachable },
989+
)?;
990+
Ok(())
991+
}
992+
979993
#[inline(always)]
980994
fn binary_ptr_op(
981995
ecx: &MiriInterpCx<'mir, 'tcx>,

src/tools/miri/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

src/tools/miri/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

src/tools/miri/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

src/tools/miri/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: 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
}

src/tools/miri/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

src/tools/miri/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
}

src/tools/miri/tests/fail/terminate-terminator.stderr

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,41 @@ warning: You have explicitly enabled MIR optimizations, overriding Miri's defaul
33
thread 'main' panicked at $DIR/terminate-terminator.rs:LL:CC:
44
explicit panic
55
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
6-
error: abnormal termination: panic in a function that cannot unwind
6+
thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
7+
panic in a function that cannot unwind
8+
stack backtrace:
9+
thread caused non-unwinding panic. aborting.
10+
error: abnormal termination: the program aborted execution
11+
--> RUSTLIB/std/src/sys/PLATFORM/mod.rs:LL:CC
12+
|
13+
LL | ABORT();
14+
| ^ the program aborted execution
15+
|
16+
= note: inside `std::sys::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/PLATFORM/mod.rs:LL:CC
17+
= note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC
18+
= note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC
19+
= 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
20+
= note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC
21+
= note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC
22+
= note: inside `core::panicking::panic_cannot_unwind` at RUSTLIB/core/src/panicking.rs:LL:CC
23+
note: inside `has_cleanup`
724
--> $DIR/terminate-terminator.rs:LL:CC
825
|
926
LL | / fn has_cleanup() {
10-
LL | |
1127
LL | | let _f = Foo;
1228
LL | | panic!();
1329
LL | | }
14-
| |_^ panic in a function that cannot unwind
15-
|
16-
= note: inside `has_cleanup` at $DIR/terminate-terminator.rs:LL:CC
30+
| |_^
1731
note: inside `panic_abort`
1832
--> $DIR/terminate-terminator.rs:LL:CC
1933
|
2034
LL | has_cleanup();
21-
| ^^^^^^^^^^^^^
35+
| ^
2236
note: inside `main`
2337
--> $DIR/terminate-terminator.rs:LL:CC
2438
|
2539
LL | panic_abort();
26-
| ^^^^^^^^^^^^^
40+
| ^
2741

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

src/tools/miri/tests/fail/unwind-action-terminate.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
//@error-in-other-file: aborted execution
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"
16
#![feature(c_unwind)]
27

38
extern "C" fn panic_abort() {
4-
//~^ ERROR: panic in a function that cannot unwind
59
panic!()
610
}
711

src/tools/miri/tests/fail/unwind-action-terminate.stderr

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,35 @@
11
thread 'main' panicked at $DIR/unwind-action-terminate.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 `panic_abort`
522
--> $DIR/unwind-action-terminate.rs:LL:CC
623
|
724
LL | / extern "C" fn panic_abort() {
8-
LL | |
925
LL | | panic!()
1026
LL | | }
11-
| |_^ panic in a function that cannot unwind
12-
|
13-
= note: inside `panic_abort` at $DIR/unwind-action-terminate.rs:LL:CC
27+
| |_^
1428
note: inside `main`
1529
--> $DIR/unwind-action-terminate.rs:LL:CC
1630
|
1731
LL | panic_abort();
18-
| ^^^^^^^^^^^^^
32+
| ^
1933

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

0 commit comments

Comments
 (0)