Skip to content

Commit 5c6a7e7

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 85ee7e6 + 0277351 commit 5c6a7e7

File tree

66 files changed

+408
-243
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+408
-243
lines changed

compiler/rustc_borrowck/src/invalidation.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,9 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
159159

160160
self.mutate_place(location, *resume_arg, Deep);
161161
}
162-
TerminatorKind::Resume | TerminatorKind::Return | TerminatorKind::GeneratorDrop => {
162+
TerminatorKind::UnwindResume
163+
| TerminatorKind::Return
164+
| TerminatorKind::GeneratorDrop => {
163165
// Invalidate all borrows of local places
164166
let borrow_set = self.borrow_set;
165167
let start = self.location_table.start_index(location);
@@ -200,7 +202,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
200202
}
201203
}
202204
TerminatorKind::Goto { target: _ }
203-
| TerminatorKind::Terminate
205+
| TerminatorKind::UnwindTerminate
204206
| TerminatorKind::Unreachable
205207
| TerminatorKind::FalseEdge { real_target: _, imaginary_target: _ }
206208
| TerminatorKind::FalseUnwind { real_target: _, unwind: _ } => {

compiler/rustc_borrowck/src/lib.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -770,9 +770,9 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
770770
}
771771

772772
TerminatorKind::Goto { target: _ }
773-
| TerminatorKind::Terminate
773+
| TerminatorKind::UnwindTerminate
774774
| TerminatorKind::Unreachable
775-
| TerminatorKind::Resume
775+
| TerminatorKind::UnwindResume
776776
| TerminatorKind::Return
777777
| TerminatorKind::GeneratorDrop
778778
| TerminatorKind::FalseEdge { real_target: _, imaginary_target: _ }
@@ -803,7 +803,9 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
803803
}
804804
}
805805

806-
TerminatorKind::Resume | TerminatorKind::Return | TerminatorKind::GeneratorDrop => {
806+
TerminatorKind::UnwindResume
807+
| TerminatorKind::Return
808+
| TerminatorKind::GeneratorDrop => {
807809
// Returning from the function implicitly kills storage for all locals and statics.
808810
// Often, the storage will already have been killed by an explicit
809811
// StorageDead, but we don't always emit those (notably on unwind paths),
@@ -815,7 +817,7 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
815817
}
816818
}
817819

818-
TerminatorKind::Terminate
820+
TerminatorKind::UnwindTerminate
819821
| TerminatorKind::Assert { .. }
820822
| TerminatorKind::Call { .. }
821823
| TerminatorKind::Drop { .. }

compiler/rustc_borrowck/src/type_check/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1333,8 +1333,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
13331333
debug!("terminator kind: {:?}", term.kind);
13341334
match &term.kind {
13351335
TerminatorKind::Goto { .. }
1336-
| TerminatorKind::Resume
1337-
| TerminatorKind::Terminate
1336+
| TerminatorKind::UnwindResume
1337+
| TerminatorKind::UnwindTerminate
13381338
| TerminatorKind::Return
13391339
| TerminatorKind::GeneratorDrop
13401340
| TerminatorKind::Unreachable
@@ -1608,12 +1608,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
16081608
self.assert_iscleanup(body, block_data, *target, is_cleanup);
16091609
}
16101610
}
1611-
TerminatorKind::Resume => {
1611+
TerminatorKind::UnwindResume => {
16121612
if !is_cleanup {
16131613
span_mirbug!(self, block_data, "resume on non-cleanup block!")
16141614
}
16151615
}
1616-
TerminatorKind::Terminate => {
1616+
TerminatorKind::UnwindTerminate => {
16171617
if !is_cleanup {
16181618
span_mirbug!(self, block_data, "abort on non-cleanup block!")
16191619
}

compiler/rustc_codegen_cranelift/src/base.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -474,10 +474,10 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
474474
*destination,
475475
);
476476
}
477-
TerminatorKind::Terminate => {
477+
TerminatorKind::UnwindTerminate => {
478478
codegen_panic_cannot_unwind(fx, source_info);
479479
}
480-
TerminatorKind::Resume => {
480+
TerminatorKind::UnwindResume => {
481481
// FIXME implement unwinding
482482
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
483483
}

compiler/rustc_codegen_cranelift/src/constant.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -550,8 +550,8 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
550550
match &bb_data.terminator().kind {
551551
TerminatorKind::Goto { .. }
552552
| TerminatorKind::SwitchInt { .. }
553-
| TerminatorKind::Resume
554-
| TerminatorKind::Terminate
553+
| TerminatorKind::UnwindResume
554+
| TerminatorKind::UnwindTerminate
555555
| TerminatorKind::Return
556556
| TerminatorKind::Unreachable
557557
| TerminatorKind::Drop { .. }

compiler/rustc_codegen_ssa/src/mir/analyze.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,8 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec<mir::BasicBlock, CleanupKi
284284
for (bb, data) in mir.basic_blocks.iter_enumerated() {
285285
match data.terminator().kind {
286286
TerminatorKind::Goto { .. }
287-
| TerminatorKind::Resume
288-
| TerminatorKind::Terminate
287+
| TerminatorKind::UnwindResume
288+
| TerminatorKind::UnwindTerminate
289289
| TerminatorKind::Return
290290
| TerminatorKind::GeneratorDrop
291291
| TerminatorKind::Unreachable

compiler/rustc_codegen_ssa/src/mir/block.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1224,12 +1224,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
12241224

12251225
self.set_debug_loc(bx, terminator.source_info);
12261226
match terminator.kind {
1227-
mir::TerminatorKind::Resume => {
1227+
mir::TerminatorKind::UnwindResume => {
12281228
self.codegen_resume_terminator(helper, bx);
12291229
MergingSucc::False
12301230
}
12311231

1232-
mir::TerminatorKind::Terminate => {
1232+
mir::TerminatorKind::UnwindTerminate => {
12331233
self.codegen_terminate_terminator(helper, bx, terminator);
12341234
MergingSucc::False
12351235
}

compiler/rustc_const_eval/src/const_eval/error.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ pub enum ConstEvalErrKind {
1818
ModifiedGlobal,
1919
AssertFailure(AssertKind<ConstInt>),
2020
Panic { msg: Symbol, line: u32, col: u32, file: Symbol },
21-
Abort(String),
2221
}
2322

2423
impl MachineStopType for ConstEvalErrKind {
@@ -30,7 +29,6 @@ impl MachineStopType for ConstEvalErrKind {
3029
ModifiedGlobal => const_eval_modified_global,
3130
Panic { .. } => const_eval_panic,
3231
AssertFailure(x) => x.diagnostic_message(),
33-
Abort(msg) => msg.to_string().into(),
3432
}
3533
}
3634
fn add_args(
@@ -39,7 +37,7 @@ impl MachineStopType for ConstEvalErrKind {
3937
) {
4038
use ConstEvalErrKind::*;
4139
match *self {
42-
ConstAccessesStatic | ModifiedGlobal | Abort(_) => {}
40+
ConstAccessesStatic | ModifiedGlobal => {}
4341
AssertFailure(kind) => kind.add_args(adder),
4442
Panic { msg, line, col, file } => {
4543
adder("msg".into(), msg.into_diagnostic_arg());

compiler/rustc_const_eval/src/const_eval/machine.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,13 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
464464
Ok(Some((ecx.load_mir(instance.def, None)?, orig_instance)))
465465
}
466466

467+
fn panic_nounwind(ecx: &mut InterpCx<'mir, 'tcx, Self>, msg: &str) -> InterpResult<'tcx> {
468+
let msg = Symbol::intern(msg);
469+
let span = ecx.find_closest_untracked_caller_location();
470+
let (file, line, col) = ecx.location_triple_for_span(span);
471+
Err(ConstEvalErrKind::Panic { msg, file, line, col }.into())
472+
}
473+
467474
fn call_intrinsic(
468475
ecx: &mut InterpCx<'mir, 'tcx, Self>,
469476
instance: ty::Instance<'tcx>,
@@ -584,10 +591,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
584591
Err(ConstEvalErrKind::AssertFailure(err).into())
585592
}
586593

587-
fn abort(_ecx: &mut InterpCx<'mir, 'tcx, Self>, msg: String) -> InterpResult<'tcx, !> {
588-
Err(ConstEvalErrKind::Abort(msg).into())
589-
}
590-
591594
fn binary_ptr_op(
592595
_ecx: &InterpCx<'mir, 'tcx, Self>,
593596
_bin_op: mir::BinOp,

compiler/rustc_const_eval/src/interpret/eval_context.rs

+5-1
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/intrinsics.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -125,15 +125,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
125125
) -> InterpResult<'tcx, bool> {
126126
let instance_args = instance.args;
127127
let intrinsic_name = self.tcx.item_name(instance.def_id());
128-
129-
// First handle intrinsics without return place.
130-
let ret = match ret {
131-
None => match intrinsic_name {
132-
sym::abort => M::abort(self, "the program aborted execution".to_owned())?,
133-
// Unsupported diverging intrinsic.
134-
_ => return Ok(false),
135-
},
136-
Some(p) => p,
128+
let Some(ret) = ret else {
129+
// We don't support any intrinsic without return place.
130+
return Ok(false);
137131
};
138132

139133
match intrinsic_name {
@@ -410,7 +404,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
410404
ValidityRequirement::Uninit => bug!("assert_uninit_valid doesn't exist"),
411405
};
412406

413-
M::abort(self, msg)?;
407+
M::panic_nounwind(self, &msg)?;
408+
// Skip the `go_to_block` at the end.
409+
return Ok(true);
414410
}
415411
}
416412
sym::simd_insert => {

compiler/rustc_const_eval/src/interpret/machine.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -218,10 +218,11 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
218218
unwind: mir::UnwindAction,
219219
) -> InterpResult<'tcx>;
220220

221-
/// Called to abort evaluation.
222-
fn abort(_ecx: &mut InterpCx<'mir, 'tcx, Self>, _msg: String) -> InterpResult<'tcx, !> {
223-
throw_unsup_format!("aborting execution is not supported")
224-
}
221+
/// Called to trigger a non-unwinding panic.
222+
fn panic_nounwind(_ecx: &mut InterpCx<'mir, 'tcx, Self>, msg: &str) -> InterpResult<'tcx>;
223+
224+
/// Called when unwinding reached a state where execution should be terminated.
225+
fn unwind_terminate(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx>;
225226

226227
/// Called for all binary operations where the LHS has pointer type.
227228
///
@@ -499,6 +500,11 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
499500
false
500501
}
501502

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

compiler/rustc_const_eval/src/interpret/terminator.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -196,15 +196,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
196196
}
197197
}
198198

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

204203
// When we encounter Resume, we've finished unwinding
205204
// cleanup for the current stack frame. We pop it in order
206205
// to continue unwinding the next frame
207-
Resume => {
206+
UnwindResume => {
208207
trace!("unwinding: resuming from cleanup");
209208
// By definition, a Resume terminator means
210209
// that we're unwinding

compiler/rustc_const_eval/src/transform/check_consts/check.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1037,7 +1037,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
10371037
self.check_op(ops::Generator(hir::GeneratorKind::Gen))
10381038
}
10391039

1040-
TerminatorKind::Terminate => {
1040+
TerminatorKind::UnwindTerminate => {
10411041
// Cleanup blocks are skipped for const checking (see `visit_basic_block_data`).
10421042
span_bug!(self.span, "`Terminate` terminator outside of cleanup block")
10431043
}
@@ -1046,7 +1046,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
10461046
| TerminatorKind::FalseEdge { .. }
10471047
| TerminatorKind::FalseUnwind { .. }
10481048
| TerminatorKind::Goto { .. }
1049-
| TerminatorKind::Resume
1049+
| TerminatorKind::UnwindResume
10501050
| TerminatorKind::Return
10511051
| TerminatorKind::SwitchInt { .. }
10521052
| TerminatorKind::Unreachable => {}

compiler/rustc_const_eval/src/transform/check_consts/post_drop_elaboration.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,15 @@ impl<'tcx> Visitor<'tcx> for CheckLiveDrops<'_, 'tcx> {
106106
}
107107
}
108108

109-
mir::TerminatorKind::Terminate
109+
mir::TerminatorKind::UnwindTerminate
110110
| mir::TerminatorKind::Call { .. }
111111
| mir::TerminatorKind::Assert { .. }
112112
| mir::TerminatorKind::FalseEdge { .. }
113113
| mir::TerminatorKind::FalseUnwind { .. }
114114
| mir::TerminatorKind::GeneratorDrop
115115
| mir::TerminatorKind::Goto { .. }
116116
| mir::TerminatorKind::InlineAsm { .. }
117-
| mir::TerminatorKind::Resume
117+
| mir::TerminatorKind::UnwindResume
118118
| mir::TerminatorKind::Return
119119
| mir::TerminatorKind::SwitchInt { .. }
120120
| mir::TerminatorKind::Unreachable

compiler/rustc_const_eval/src/transform/validate.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -492,19 +492,19 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
492492
);
493493
}
494494
}
495-
TerminatorKind::Resume => {
495+
TerminatorKind::UnwindResume => {
496496
let bb = location.block;
497497
if !self.body.basic_blocks[bb].is_cleanup {
498-
self.fail(location, "Cannot `Resume` from non-cleanup basic block")
498+
self.fail(location, "Cannot `UnwindResume` from non-cleanup basic block")
499499
}
500500
if !self.can_unwind {
501-
self.fail(location, "Cannot `Resume` in a function that cannot unwind")
501+
self.fail(location, "Cannot `UnwindResume` in a function that cannot unwind")
502502
}
503503
}
504-
TerminatorKind::Terminate => {
504+
TerminatorKind::UnwindTerminate => {
505505
let bb = location.block;
506506
if !self.body.basic_blocks[bb].is_cleanup {
507-
self.fail(location, "Cannot `Terminate` from non-cleanup basic block")
507+
self.fail(location, "Cannot `UnwindTerminate` from non-cleanup basic block")
508508
}
509509
}
510510
TerminatorKind::Return => {
@@ -1232,8 +1232,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
12321232
| TerminatorKind::FalseUnwind { .. }
12331233
| TerminatorKind::InlineAsm { .. }
12341234
| TerminatorKind::GeneratorDrop
1235-
| TerminatorKind::Resume
1236-
| TerminatorKind::Terminate
1235+
| TerminatorKind::UnwindResume
1236+
| TerminatorKind::UnwindTerminate
12371237
| TerminatorKind::Return
12381238
| TerminatorKind::Unreachable => {}
12391239
}

compiler/rustc_middle/src/mir/patch.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl<'tcx> MirPatch<'tcx> {
3535

3636
for (bb, block) in body.basic_blocks.iter_enumerated() {
3737
// Check if we already have a resume block
38-
if let TerminatorKind::Resume = block.terminator().kind && block.statements.is_empty() {
38+
if let TerminatorKind::UnwindResume = block.terminator().kind && block.statements.is_empty() {
3939
result.resume_block = Some(bb);
4040
continue;
4141
}
@@ -50,7 +50,7 @@ impl<'tcx> MirPatch<'tcx> {
5050
}
5151

5252
// Check if we already have a terminate block
53-
if let TerminatorKind::Terminate = block.terminator().kind && block.statements.is_empty() {
53+
if let TerminatorKind::UnwindTerminate = block.terminator().kind && block.statements.is_empty() {
5454
result.terminate_block = Some(bb);
5555
continue;
5656
}
@@ -68,7 +68,7 @@ impl<'tcx> MirPatch<'tcx> {
6868
statements: vec![],
6969
terminator: Some(Terminator {
7070
source_info: SourceInfo::outermost(self.body_span),
71-
kind: TerminatorKind::Resume,
71+
kind: TerminatorKind::UnwindResume,
7272
}),
7373
is_cleanup: true,
7474
});
@@ -102,7 +102,7 @@ impl<'tcx> MirPatch<'tcx> {
102102
statements: vec![],
103103
terminator: Some(Terminator {
104104
source_info: SourceInfo::outermost(self.body_span),
105-
kind: TerminatorKind::Terminate,
105+
kind: TerminatorKind::UnwindTerminate,
106106
}),
107107
is_cleanup: true,
108108
});

0 commit comments

Comments
 (0)