Skip to content

Commit c28e7b2

Browse files
committed
Auto merge of #102906 - nbdd0121:mir, r=wesleywiser,tmiasko
Refactor unwind in MIR This makes unwinding from current `Option<BasicBlock>` into ```rust enum UnwindAction { Continue, Cleanup(BasicBlock), Unreachable, Terminate, } ``` cc `@JakobDegen` `@RalfJung` `@Amanieu`
2 parents fb39767 + 5ebde9e commit c28e7b2

13 files changed

+84
-39
lines changed

src/helpers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -951,7 +951,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
951951
if this.machine.panic_on_unsupported {
952952
// message is slightly different here to make automated analysis easier
953953
let error_msg = format!("unsupported Miri functionality: {}", error_msg.as_ref());
954-
this.start_panic(error_msg.as_ref(), StackPopUnwind::Skip)?;
954+
this.start_panic(error_msg.as_ref(), mir::UnwindAction::Continue)?;
955955
Ok(())
956956
} else {
957957
throw_unsup_format!("{}", error_msg.as_ref());

src/machine.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -834,7 +834,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
834834
args: &[OpTy<'tcx, Provenance>],
835835
dest: &PlaceTy<'tcx, Provenance>,
836836
ret: Option<mir::BasicBlock>,
837-
unwind: StackPopUnwind,
837+
unwind: mir::UnwindAction,
838838
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
839839
ecx.find_mir_or_eval_fn(instance, abi, args, dest, ret, unwind)
840840
}
@@ -847,7 +847,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
847847
args: &[OpTy<'tcx, Provenance>],
848848
dest: &PlaceTy<'tcx, Provenance>,
849849
ret: Option<mir::BasicBlock>,
850-
_unwind: StackPopUnwind,
850+
_unwind: mir::UnwindAction,
851851
) -> InterpResult<'tcx> {
852852
ecx.call_dlsym(fn_val, abi, args, dest, ret)
853853
}
@@ -859,7 +859,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
859859
args: &[OpTy<'tcx, Provenance>],
860860
dest: &PlaceTy<'tcx, Provenance>,
861861
ret: Option<mir::BasicBlock>,
862-
unwind: StackPopUnwind,
862+
unwind: mir::UnwindAction,
863863
) -> InterpResult<'tcx> {
864864
ecx.call_intrinsic(instance, args, dest, ret, unwind)
865865
}
@@ -868,7 +868,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
868868
fn assert_panic(
869869
ecx: &mut MiriInterpCx<'mir, 'tcx>,
870870
msg: &mir::AssertMessage<'tcx>,
871-
unwind: Option<mir::BasicBlock>,
871+
unwind: mir::UnwindAction,
872872
) -> InterpResult<'tcx> {
873873
ecx.assert_panic(msg, unwind)
874874
}

src/shims/foreign_items.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
258258
args: &[OpTy<'tcx, Provenance>],
259259
dest: &PlaceTy<'tcx, Provenance>,
260260
ret: Option<mir::BasicBlock>,
261-
unwind: StackPopUnwind,
261+
unwind: mir::UnwindAction,
262262
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
263263
let this = self.eval_context_mut();
264264
let link_name = this.item_link_name(def_id);

src/shims/intrinsics/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
2626
args: &[OpTy<'tcx, Provenance>],
2727
dest: &PlaceTy<'tcx, Provenance>,
2828
ret: Option<mir::BasicBlock>,
29-
_unwind: StackPopUnwind,
29+
_unwind: mir::UnwindAction,
3030
) -> InterpResult<'tcx> {
3131
let this = self.eval_context_mut();
3232

src/shims/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
3434
args: &[OpTy<'tcx, Provenance>],
3535
dest: &PlaceTy<'tcx, Provenance>,
3636
ret: Option<mir::BasicBlock>,
37-
unwind: StackPopUnwind,
37+
unwind: mir::UnwindAction,
3838
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
3939
let this = self.eval_context_mut();
4040
trace!("eval_fn_call: {:#?}, {:?}", instance, dest);
@@ -70,7 +70,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
7070
align_op: &OpTy<'tcx, Provenance>,
7171
dest: &PlaceTy<'tcx, Provenance>,
7272
ret: Option<mir::BasicBlock>,
73-
unwind: StackPopUnwind,
73+
unwind: mir::UnwindAction,
7474
) -> InterpResult<'tcx, bool> {
7575
let this = self.eval_context_mut();
7676
let ret = ret.unwrap();

src/shims/panic.rs

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
5353
abi: Abi,
5454
link_name: Symbol,
5555
args: &[OpTy<'tcx, Provenance>],
56-
unwind: StackPopUnwind,
56+
unwind: mir::UnwindAction,
5757
) -> InterpResult<'tcx> {
5858
let this = self.eval_context_mut();
5959

@@ -106,7 +106,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
106106
&[data.into()],
107107
None,
108108
// Directly return to caller.
109-
StackPopCleanup::Goto { ret: Some(ret), unwind: StackPopUnwind::Skip },
109+
StackPopCleanup::Goto { ret: Some(ret), unwind: mir::UnwindAction::Continue },
110110
)?;
111111

112112
// We ourselves will return `0`, eventually (will be overwritten if we catch a panic).
@@ -157,7 +157,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
157157
&[catch_unwind.data.into(), payload.into()],
158158
None,
159159
// Directly return to caller of `try`.
160-
StackPopCleanup::Goto { ret: Some(catch_unwind.ret), unwind: StackPopUnwind::Skip },
160+
StackPopCleanup::Goto { ret: Some(catch_unwind.ret), unwind: mir::UnwindAction::Continue },
161161
)?;
162162

163163
// We pushed a new stack frame, the engine should not do any jumping now!
@@ -168,7 +168,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
168168
}
169169

170170
/// Start a panic in the interpreter with the given message as payload.
171-
fn start_panic(&mut self, msg: &str, unwind: StackPopUnwind) -> InterpResult<'tcx> {
171+
fn start_panic(&mut self, msg: &str, unwind: mir::UnwindAction) -> InterpResult<'tcx> {
172172
let this = self.eval_context_mut();
173173

174174
// First arg: message.
@@ -189,7 +189,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
189189
fn assert_panic(
190190
&mut self,
191191
msg: &mir::AssertMessage<'tcx>,
192-
unwind: Option<mir::BasicBlock>,
192+
unwind: mir::UnwindAction,
193193
) -> InterpResult<'tcx> {
194194
use rustc_middle::mir::AssertKind::*;
195195
let this = self.eval_context_mut();
@@ -213,10 +213,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
213213
None,
214214
StackPopCleanup::Goto {
215215
ret: None,
216-
unwind: match unwind {
217-
Some(cleanup) => StackPopUnwind::Cleanup(cleanup),
218-
None => StackPopUnwind::Skip,
219-
},
216+
unwind,
220217
},
221218
)?;
222219
}
@@ -240,10 +237,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
240237
None,
241238
StackPopCleanup::Goto {
242239
ret: None,
243-
unwind: match unwind {
244-
Some(cleanup) => StackPopUnwind::Cleanup(cleanup),
245-
None => StackPopUnwind::Skip,
246-
},
240+
unwind,
247241
},
248242
)?;
249243
}
@@ -252,10 +246,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
252246
// Forward everything else to `panic` lang item.
253247
this.start_panic(
254248
msg.description(),
255-
match unwind {
256-
Some(cleanup) => StackPopUnwind::Cleanup(cleanup),
257-
None => StackPopUnwind::Skip,
258-
},
249+
unwind,
259250
)?;
260251
}
261252
}

tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
thread 'main' panicked at 'explicit panic', $DIR/exported_symbol_bad_unwind2.rs:LL:CC
22
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
3-
error: abnormal termination: the program aborted execution
3+
error: abnormal termination: panic in a function that cannot unwind
44
--> $DIR/exported_symbol_bad_unwind2.rs:LL:CC
55
|
66
LL | / extern "C-unwind" fn nounwind() {
77
LL | |
88
LL | |
99
LL | | panic!();
1010
LL | | }
11-
| |_^ the program aborted execution
11+
| |_^ panic in a function that cannot unwind
1212
|
1313
= note: inside `nounwind` at $DIR/exported_symbol_bad_unwind2.rs:LL:CC
1414
note: inside `main`

tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
thread 'main' panicked at 'explicit panic', $DIR/exported_symbol_bad_unwind2.rs:LL:CC
22
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
3-
error: abnormal termination: the program aborted execution
3+
error: abnormal termination: panic in a function that cannot unwind
44
--> $DIR/exported_symbol_bad_unwind2.rs:LL:CC
55
|
66
LL | / extern "C-unwind" fn nounwind() {
77
LL | |
88
LL | |
99
LL | | panic!();
1010
LL | | }
11-
| |_^ the program aborted execution
11+
| |_^ panic in a function that cannot unwind
1212
|
1313
= note: inside `nounwind` at $DIR/exported_symbol_bad_unwind2.rs:LL:CC
1414
note: inside `main`

tests/fail/function_calls/exported_symbol_bad_unwind2.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
#[cfg_attr(any(definition, both), rustc_nounwind)]
55
#[no_mangle]
66
extern "C-unwind" fn nounwind() {
7-
//~[definition]^ ERROR: abnormal termination: the program aborted execution
8-
//~[both]^^ ERROR: abnormal termination: the program aborted execution
7+
//~[definition]^ ERROR: abnormal termination: panic in a function that cannot unwind
8+
//~[both]^^ ERROR: abnormal termination: panic in a function that cannot unwind
99
panic!();
1010
}
1111

tests/fail/terminate-terminator.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//@compile-flags: -Zmir-opt-level=3
2+
// Enable MIR inlining to ensure that `TerminatorKind::Terminate` is generated
3+
// instead of just `UnwindAction::Terminate`.
4+
5+
#![feature(c_unwind)]
6+
7+
struct Foo;
8+
9+
impl Drop for Foo {
10+
fn drop(&mut self) {}
11+
}
12+
13+
#[inline(always)]
14+
fn has_cleanup() {
15+
//~^ ERROR: panic in a function that cannot unwind
16+
// FIXME(nbdd0121): The error should be reported at the call site.
17+
let _f = Foo;
18+
panic!();
19+
}
20+
21+
extern "C" fn panic_abort() {
22+
has_cleanup();
23+
}
24+
25+
fn main() {
26+
panic_abort();
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
thread 'main' panicked at 'explicit panic', $DIR/terminate-terminator.rs:LL:CC
2+
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
3+
error: abnormal termination: panic in a function that cannot unwind
4+
--> $DIR/terminate-terminator.rs:LL:CC
5+
|
6+
LL | / fn has_cleanup() {
7+
LL | |
8+
LL | | // FIXME(nbdd0121): The error should be reported at the call site.
9+
LL | | let _f = Foo;
10+
LL | | panic!();
11+
LL | | }
12+
| |_^ panic in a function that cannot unwind
13+
...
14+
LL | has_cleanup();
15+
| ------------- in this inlined function call
16+
|
17+
= note: inside `panic_abort` at $DIR/terminate-terminator.rs:LL:CC
18+
note: inside `main`
19+
--> $DIR/terminate-terminator.rs:LL:CC
20+
|
21+
LL | panic_abort();
22+
| ^^^^^^^^^^^^^
23+
24+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
25+
26+
error: aborting due to previous error
27+

tests/fail/abort-terminator.rs renamed to tests/fail/unwind-action-terminate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#![feature(c_unwind)]
22

33
extern "C" fn panic_abort() {
4-
//~^ ERROR: the program aborted
4+
//~^ ERROR: panic in a function that cannot unwind
55
panic!()
66
}
77

tests/fail/abort-terminator.stderr renamed to tests/fail/unwind-action-terminate.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
thread 'main' panicked at 'explicit panic', $DIR/abort-terminator.rs:LL:CC
1+
thread 'main' panicked at 'explicit panic', $DIR/unwind-action-terminate.rs:LL:CC
22
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
3-
error: abnormal termination: the program aborted execution
4-
--> $DIR/abort-terminator.rs:LL:CC
3+
error: abnormal termination: panic in a function that cannot unwind
4+
--> $DIR/unwind-action-terminate.rs:LL:CC
55
|
66
LL | / extern "C" fn panic_abort() {
77
LL | |
88
LL | | panic!()
99
LL | | }
10-
| |_^ the program aborted execution
10+
| |_^ panic in a function that cannot unwind
1111
|
12-
= note: inside `panic_abort` at $DIR/abort-terminator.rs:LL:CC
12+
= note: inside `panic_abort` at $DIR/unwind-action-terminate.rs:LL:CC
1313
note: inside `main`
14-
--> $DIR/abort-terminator.rs:LL:CC
14+
--> $DIR/unwind-action-terminate.rs:LL:CC
1515
|
1616
LL | panic_abort();
1717
| ^^^^^^^^^^^^^

0 commit comments

Comments
 (0)