Skip to content

Commit

Permalink
Auto merge of #114993 - RalfJung:panic-nounwind, r=fee1-dead
Browse files Browse the repository at this point in the history
interpret/miri: call the panic_nounwind machinery the same way codegen does
  • Loading branch information
bors committed Aug 20, 2023
2 parents 85ee7e6 + 0277351 commit 5c6a7e7
Show file tree
Hide file tree
Showing 66 changed files with 408 additions and 243 deletions.
6 changes: 4 additions & 2 deletions compiler/rustc_borrowck/src/invalidation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,9 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {

self.mutate_place(location, *resume_arg, Deep);
}
TerminatorKind::Resume | TerminatorKind::Return | TerminatorKind::GeneratorDrop => {
TerminatorKind::UnwindResume
| TerminatorKind::Return
| TerminatorKind::GeneratorDrop => {
// Invalidate all borrows of local places
let borrow_set = self.borrow_set;
let start = self.location_table.start_index(location);
Expand Down Expand Up @@ -200,7 +202,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
}
}
TerminatorKind::Goto { target: _ }
| TerminatorKind::Terminate
| TerminatorKind::UnwindTerminate
| TerminatorKind::Unreachable
| TerminatorKind::FalseEdge { real_target: _, imaginary_target: _ }
| TerminatorKind::FalseUnwind { real_target: _, unwind: _ } => {
Expand Down
10 changes: 6 additions & 4 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -770,9 +770,9 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
}

TerminatorKind::Goto { target: _ }
| TerminatorKind::Terminate
| TerminatorKind::UnwindTerminate
| TerminatorKind::Unreachable
| TerminatorKind::Resume
| TerminatorKind::UnwindResume
| TerminatorKind::Return
| TerminatorKind::GeneratorDrop
| TerminatorKind::FalseEdge { real_target: _, imaginary_target: _ }
Expand Down Expand Up @@ -803,7 +803,9 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
}
}

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

TerminatorKind::Terminate
TerminatorKind::UnwindTerminate
| TerminatorKind::Assert { .. }
| TerminatorKind::Call { .. }
| TerminatorKind::Drop { .. }
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1333,8 +1333,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
debug!("terminator kind: {:?}", term.kind);
match &term.kind {
TerminatorKind::Goto { .. }
| TerminatorKind::Resume
| TerminatorKind::Terminate
| TerminatorKind::UnwindResume
| TerminatorKind::UnwindTerminate
| TerminatorKind::Return
| TerminatorKind::GeneratorDrop
| TerminatorKind::Unreachable
Expand Down Expand Up @@ -1608,12 +1608,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
self.assert_iscleanup(body, block_data, *target, is_cleanup);
}
}
TerminatorKind::Resume => {
TerminatorKind::UnwindResume => {
if !is_cleanup {
span_mirbug!(self, block_data, "resume on non-cleanup block!")
}
}
TerminatorKind::Terminate => {
TerminatorKind::UnwindTerminate => {
if !is_cleanup {
span_mirbug!(self, block_data, "abort on non-cleanup block!")
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_cranelift/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,10 +474,10 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
*destination,
);
}
TerminatorKind::Terminate => {
TerminatorKind::UnwindTerminate => {
codegen_panic_cannot_unwind(fx, source_info);
}
TerminatorKind::Resume => {
TerminatorKind::UnwindResume => {
// FIXME implement unwinding
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_cranelift/src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,8 +550,8 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
match &bb_data.terminator().kind {
TerminatorKind::Goto { .. }
| TerminatorKind::SwitchInt { .. }
| TerminatorKind::Resume
| TerminatorKind::Terminate
| TerminatorKind::UnwindResume
| TerminatorKind::UnwindTerminate
| TerminatorKind::Return
| TerminatorKind::Unreachable
| TerminatorKind::Drop { .. }
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_ssa/src/mir/analyze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,8 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec<mir::BasicBlock, CleanupKi
for (bb, data) in mir.basic_blocks.iter_enumerated() {
match data.terminator().kind {
TerminatorKind::Goto { .. }
| TerminatorKind::Resume
| TerminatorKind::Terminate
| TerminatorKind::UnwindResume
| TerminatorKind::UnwindTerminate
| TerminatorKind::Return
| TerminatorKind::GeneratorDrop
| TerminatorKind::Unreachable
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1224,12 +1224,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {

self.set_debug_loc(bx, terminator.source_info);
match terminator.kind {
mir::TerminatorKind::Resume => {
mir::TerminatorKind::UnwindResume => {
self.codegen_resume_terminator(helper, bx);
MergingSucc::False
}

mir::TerminatorKind::Terminate => {
mir::TerminatorKind::UnwindTerminate => {
self.codegen_terminate_terminator(helper, bx, terminator);
MergingSucc::False
}
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_const_eval/src/const_eval/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ pub enum ConstEvalErrKind {
ModifiedGlobal,
AssertFailure(AssertKind<ConstInt>),
Panic { msg: Symbol, line: u32, col: u32, file: Symbol },
Abort(String),
}

impl MachineStopType for ConstEvalErrKind {
Expand All @@ -30,7 +29,6 @@ impl MachineStopType for ConstEvalErrKind {
ModifiedGlobal => const_eval_modified_global,
Panic { .. } => const_eval_panic,
AssertFailure(x) => x.diagnostic_message(),
Abort(msg) => msg.to_string().into(),
}
}
fn add_args(
Expand All @@ -39,7 +37,7 @@ impl MachineStopType for ConstEvalErrKind {
) {
use ConstEvalErrKind::*;
match *self {
ConstAccessesStatic | ModifiedGlobal | Abort(_) => {}
ConstAccessesStatic | ModifiedGlobal => {}
AssertFailure(kind) => kind.add_args(adder),
Panic { msg, line, col, file } => {
adder("msg".into(), msg.into_diagnostic_arg());
Expand Down
11 changes: 7 additions & 4 deletions compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,13 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
Ok(Some((ecx.load_mir(instance.def, None)?, orig_instance)))
}

fn panic_nounwind(ecx: &mut InterpCx<'mir, 'tcx, Self>, msg: &str) -> InterpResult<'tcx> {
let msg = Symbol::intern(msg);
let span = ecx.find_closest_untracked_caller_location();
let (file, line, col) = ecx.location_triple_for_span(span);
Err(ConstEvalErrKind::Panic { msg, file, line, col }.into())
}

fn call_intrinsic(
ecx: &mut InterpCx<'mir, 'tcx, Self>,
instance: ty::Instance<'tcx>,
Expand Down Expand Up @@ -584,10 +591,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
Err(ConstEvalErrKind::AssertFailure(err).into())
}

fn abort(_ecx: &mut InterpCx<'mir, 'tcx, Self>, msg: String) -> InterpResult<'tcx, !> {
Err(ConstEvalErrKind::Abort(msg).into())
}

fn binary_ptr_op(
_ecx: &InterpCx<'mir, 'tcx, Self>,
_bin_op: mir::BinOp,
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
mir::UnwindAction::Terminate => {
self.frame_mut().loc = Right(self.frame_mut().body.span);
M::abort(self, "panic in a function that cannot unwind".to_owned())?;
M::unwind_terminate(self)?;
// This might have pushed a new stack frame, or it terminated execution.
// Either way, `loc` will not be updated.
return Ok(());
}
};
Ok(())
Expand Down Expand Up @@ -865,6 +868,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
panic!("encountered StackPopCleanup::Root when unwinding!")
}
};
// This must be the very last thing that happens, since it can in fact push a new stack frame.
self.unwind_to_block(unwind)
} else {
// Follow the normal return edge.
Expand Down
16 changes: 6 additions & 10 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
) -> InterpResult<'tcx, bool> {
let instance_args = instance.args;
let intrinsic_name = self.tcx.item_name(instance.def_id());

// First handle intrinsics without return place.
let ret = match ret {
None => match intrinsic_name {
sym::abort => M::abort(self, "the program aborted execution".to_owned())?,
// Unsupported diverging intrinsic.
_ => return Ok(false),
},
Some(p) => p,
let Some(ret) = ret else {
// We don't support any intrinsic without return place.
return Ok(false);
};

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

M::abort(self, msg)?;
M::panic_nounwind(self, &msg)?;
// Skip the `go_to_block` at the end.
return Ok(true);
}
}
sym::simd_insert => {
Expand Down
14 changes: 10 additions & 4 deletions compiler/rustc_const_eval/src/interpret/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,11 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
unwind: mir::UnwindAction,
) -> InterpResult<'tcx>;

/// Called to abort evaluation.
fn abort(_ecx: &mut InterpCx<'mir, 'tcx, Self>, _msg: String) -> InterpResult<'tcx, !> {
throw_unsup_format!("aborting execution is not supported")
}
/// Called to trigger a non-unwinding panic.
fn panic_nounwind(_ecx: &mut InterpCx<'mir, 'tcx, Self>, msg: &str) -> InterpResult<'tcx>;

/// Called when unwinding reached a state where execution should be terminated.
fn unwind_terminate(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx>;

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

#[inline(always)]
fn unwind_terminate(_ecx: &mut InterpCx<$mir, $tcx, Self>) -> InterpResult<$tcx> {
unreachable!("unwinding cannot happen during compile-time evaluation")
}

#[inline(always)]
fn call_extra_fn(
_ecx: &mut InterpCx<$mir, $tcx, Self>,
Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_const_eval/src/interpret/terminator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,15 +196,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
}

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

// When we encounter Resume, we've finished unwinding
// cleanup for the current stack frame. We pop it in order
// to continue unwinding the next frame
Resume => {
UnwindResume => {
trace!("unwinding: resuming from cleanup");
// By definition, a Resume terminator means
// that we're unwinding
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/transform/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1037,7 +1037,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
self.check_op(ops::Generator(hir::GeneratorKind::Gen))
}

TerminatorKind::Terminate => {
TerminatorKind::UnwindTerminate => {
// Cleanup blocks are skipped for const checking (see `visit_basic_block_data`).
span_bug!(self.span, "`Terminate` terminator outside of cleanup block")
}
Expand All @@ -1046,7 +1046,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
| TerminatorKind::FalseEdge { .. }
| TerminatorKind::FalseUnwind { .. }
| TerminatorKind::Goto { .. }
| TerminatorKind::Resume
| TerminatorKind::UnwindResume
| TerminatorKind::Return
| TerminatorKind::SwitchInt { .. }
| TerminatorKind::Unreachable => {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,15 @@ impl<'tcx> Visitor<'tcx> for CheckLiveDrops<'_, 'tcx> {
}
}

mir::TerminatorKind::Terminate
mir::TerminatorKind::UnwindTerminate
| mir::TerminatorKind::Call { .. }
| mir::TerminatorKind::Assert { .. }
| mir::TerminatorKind::FalseEdge { .. }
| mir::TerminatorKind::FalseUnwind { .. }
| mir::TerminatorKind::GeneratorDrop
| mir::TerminatorKind::Goto { .. }
| mir::TerminatorKind::InlineAsm { .. }
| mir::TerminatorKind::Resume
| mir::TerminatorKind::UnwindResume
| mir::TerminatorKind::Return
| mir::TerminatorKind::SwitchInt { .. }
| mir::TerminatorKind::Unreachable
Expand Down
14 changes: 7 additions & 7 deletions compiler/rustc_const_eval/src/transform/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,19 +492,19 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
);
}
}
TerminatorKind::Resume => {
TerminatorKind::UnwindResume => {
let bb = location.block;
if !self.body.basic_blocks[bb].is_cleanup {
self.fail(location, "Cannot `Resume` from non-cleanup basic block")
self.fail(location, "Cannot `UnwindResume` from non-cleanup basic block")
}
if !self.can_unwind {
self.fail(location, "Cannot `Resume` in a function that cannot unwind")
self.fail(location, "Cannot `UnwindResume` in a function that cannot unwind")
}
}
TerminatorKind::Terminate => {
TerminatorKind::UnwindTerminate => {
let bb = location.block;
if !self.body.basic_blocks[bb].is_cleanup {
self.fail(location, "Cannot `Terminate` from non-cleanup basic block")
self.fail(location, "Cannot `UnwindTerminate` from non-cleanup basic block")
}
}
TerminatorKind::Return => {
Expand Down Expand Up @@ -1232,8 +1232,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
| TerminatorKind::FalseUnwind { .. }
| TerminatorKind::InlineAsm { .. }
| TerminatorKind::GeneratorDrop
| TerminatorKind::Resume
| TerminatorKind::Terminate
| TerminatorKind::UnwindResume
| TerminatorKind::UnwindTerminate
| TerminatorKind::Return
| TerminatorKind::Unreachable => {}
}
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_middle/src/mir/patch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl<'tcx> MirPatch<'tcx> {

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

// Check if we already have a terminate block
if let TerminatorKind::Terminate = block.terminator().kind && block.statements.is_empty() {
if let TerminatorKind::UnwindTerminate = block.terminator().kind && block.statements.is_empty() {
result.terminate_block = Some(bb);
continue;
}
Expand All @@ -68,7 +68,7 @@ impl<'tcx> MirPatch<'tcx> {
statements: vec![],
terminator: Some(Terminator {
source_info: SourceInfo::outermost(self.body_span),
kind: TerminatorKind::Resume,
kind: TerminatorKind::UnwindResume,
}),
is_cleanup: true,
});
Expand Down Expand Up @@ -102,7 +102,7 @@ impl<'tcx> MirPatch<'tcx> {
statements: vec![],
terminator: Some(Terminator {
source_info: SourceInfo::outermost(self.body_span),
kind: TerminatorKind::Terminate,
kind: TerminatorKind::UnwindTerminate,
}),
is_cleanup: true,
});
Expand Down
Loading

0 comments on commit 5c6a7e7

Please sign in to comment.