From ae0b24fe5504b469bdb824646a93da96a66a4ea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Tue, 28 Nov 2023 00:00:00 +0000 Subject: [PATCH] Fix coroutine validation for mixed panic strategy Validation introduced in #113124 allows UnwindAction::Continue and TerminatorKind::Resume to occur only in functions with ABI that can unwind. The function ABI depends on the panic strategy, which can vary across crates. Usually MIR is built and validated in the same crate. The coroutine drop glue thus far was an exception. As a result validation could fail when mixing different panic strategies. Avoid the problem by executing AbortUnwindingCalls along with the validation. (cherry picked from commit 5161b22143bf9a726cfd69d19bef11552d0ed519) --- compiler/rustc_mir_transform/src/coroutine.rs | 9 --------- compiler/rustc_mir_transform/src/shim.rs | 6 ++++-- tests/ui/coroutine/auxiliary/unwind-aux.rs | 11 +++++++++++ tests/ui/coroutine/unwind-abort-mix.rs | 13 +++++++++++++ 4 files changed, 28 insertions(+), 11 deletions(-) create mode 100644 tests/ui/coroutine/auxiliary/unwind-aux.rs create mode 100644 tests/ui/coroutine/unwind-abort-mix.rs diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index dfafd8598306b..abaed103fab1f 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -1153,18 +1153,9 @@ fn create_coroutine_drop_shim<'tcx>( simplify::remove_dead_blocks(&mut body); // Update the body's def to become the drop glue. - // This needs to be updated before the AbortUnwindingCalls pass. let coroutine_instance = body.source.instance; let drop_in_place = tcx.require_lang_item(LangItem::DropInPlace, None); let drop_instance = InstanceDef::DropGlue(drop_in_place, Some(coroutine_ty)); - body.source.instance = drop_instance; - - pm::run_passes_no_validate( - tcx, - &mut body, - &[&abort_unwinding_calls::AbortUnwindingCalls], - None, - ); // Temporary change MirSource to coroutine's instance so that dump_mir produces more sensible // filename. diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 4ae5ea4c8d68f..ab7961321b3f9 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -74,11 +74,13 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<' let mut body = EarlyBinder::bind(body.clone()).instantiate(tcx, args); debug!("make_shim({:?}) = {:?}", instance, body); - // Run empty passes to mark phase change and perform validation. pm::run_passes( tcx, &mut body, - &[], + &[ + &abort_unwinding_calls::AbortUnwindingCalls, + &add_call_guards::CriticalCallEdges, + ], Some(MirPhase::Runtime(RuntimePhase::Optimized)), ); diff --git a/tests/ui/coroutine/auxiliary/unwind-aux.rs b/tests/ui/coroutine/auxiliary/unwind-aux.rs new file mode 100644 index 0000000000000..215d676911633 --- /dev/null +++ b/tests/ui/coroutine/auxiliary/unwind-aux.rs @@ -0,0 +1,11 @@ +// compile-flags: -Cpanic=unwind --crate-type=lib +// no-prefer-dynamic +// edition:2021 + +#![feature(coroutines)] +pub fn run(a: T) { + let _ = move || { + drop(a); + yield; + }; +} diff --git a/tests/ui/coroutine/unwind-abort-mix.rs b/tests/ui/coroutine/unwind-abort-mix.rs new file mode 100644 index 0000000000000..869b3e4f43347 --- /dev/null +++ b/tests/ui/coroutine/unwind-abort-mix.rs @@ -0,0 +1,13 @@ +// Ensure that coroutine drop glue is valid when mixing different panic +// strategies. Regression test for #116953. +// +// no-prefer-dynamic +// build-pass +// aux-build:unwind-aux.rs +// compile-flags: -Cpanic=abort +// needs-unwind +extern crate unwind_aux; + +pub fn main() { + unwind_aux::run(String::new()); +}