From f45f8262078bde0435560a1e17fb749d0f46dc30 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Mon, 16 May 2022 21:46:20 -0700 Subject: [PATCH 1/2] Update MIR passes that assumed inline can never unwind. --- compiler/rustc_mir_transform/src/abort_unwinding_calls.rs | 7 +++++++ compiler/rustc_mir_transform/src/generator.rs | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs index ade6555f4d2c1..11980382ffdb2 100644 --- a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs +++ b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs @@ -1,4 +1,5 @@ use crate::MirPass; +use rustc_ast::InlineAsmOptions; use rustc_hir::def::DefKind; use rustc_middle::mir::*; use rustc_middle::ty::layout; @@ -85,6 +86,12 @@ impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls { TerminatorKind::Assert { .. } | TerminatorKind::FalseUnwind { .. } => { layout::fn_can_unwind(tcx, None, Abi::Rust) } + TerminatorKind::InlineAsm { options, .. } => { + options.contains(InlineAsmOptions::MAY_UNWIND) + } + _ if terminator.unwind().is_some() => { + span_bug!(span, "unexpected terminator that may unwind {:?}", terminator) + } _ => continue, }; diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index b7dec57b75768..9e7bf5c792951 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -1042,8 +1042,7 @@ fn can_unwind<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> bool { | TerminatorKind::Unreachable | TerminatorKind::GeneratorDrop | TerminatorKind::FalseEdge { .. } - | TerminatorKind::FalseUnwind { .. } - | TerminatorKind::InlineAsm { .. } => {} + | TerminatorKind::FalseUnwind { .. } => {} // Resume will *continue* unwinding, but if there's no other unwinding terminator it // will never be reached. @@ -1057,6 +1056,7 @@ fn can_unwind<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> bool { TerminatorKind::Drop { .. } | TerminatorKind::DropAndReplace { .. } | TerminatorKind::Call { .. } + | TerminatorKind::InlineAsm { .. } | TerminatorKind::Assert { .. } => return true, } } From af7f53d6d0f05b953d9364ae81339f6e185a9957 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Mon, 16 May 2022 21:51:20 -0700 Subject: [PATCH 2/2] Add mir-opt test for asm_unwind + panic=abort --- ...c_abort.main.AbortUnwindingCalls.after.mir | 24 +++++++++++++++++++ src/test/mir-opt/asm_unwind_panic_abort.rs | 16 +++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 src/test/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir create mode 100644 src/test/mir-opt/asm_unwind_panic_abort.rs diff --git a/src/test/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir b/src/test/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir new file mode 100644 index 0000000000000..44d722d6f9bff --- /dev/null +++ b/src/test/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir @@ -0,0 +1,24 @@ +// MIR for `main` after AbortUnwindingCalls + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/asm_unwind_panic_abort.rs:12:11: 12:11 + let _1: (); // in scope 0 at $DIR/asm_unwind_panic_abort.rs:14:9: 14:49 + scope 1 { + } + + bb0: { + StorageLive(_1); // scope 1 at $DIR/asm_unwind_panic_abort.rs:14:9: 14:49 + _1 = const (); // scope 1 at $DIR/asm_unwind_panic_abort.rs:14:9: 14:49 + asm!("", options(MAY_UNWIND)) -> [return: bb1, unwind: bb2]; // scope 1 at $DIR/asm_unwind_panic_abort.rs:14:9: 14:49 + } + + bb1: { + StorageDead(_1); // scope 1 at $DIR/asm_unwind_panic_abort.rs:14:48: 14:49 + _0 = const (); // scope 1 at $DIR/asm_unwind_panic_abort.rs:13:5: 15:6 + return; // scope 0 at $DIR/asm_unwind_panic_abort.rs:16:2: 16:2 + } + + bb2 (cleanup): { + abort; // scope 0 at $DIR/asm_unwind_panic_abort.rs:12:1: 16:2 + } +} diff --git a/src/test/mir-opt/asm_unwind_panic_abort.rs b/src/test/mir-opt/asm_unwind_panic_abort.rs new file mode 100644 index 0000000000000..8201d54348a83 --- /dev/null +++ b/src/test/mir-opt/asm_unwind_panic_abort.rs @@ -0,0 +1,16 @@ +//! Tests that unwinding from an asm block is caught and forced to abort +//! when `-C panic=abort`. + +// min-llvm-version: 13.0.0 +// only-x86_64 +// compile-flags: -C panic=abort +// no-prefer-dynamic + +#![feature(asm_unwind)] + +// EMIT_MIR asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir +fn main() { + unsafe { + std::arch::asm!("", options(may_unwind)); + } +}