about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTomasz Miąsko <tomasz.miasko@gmail.com>2023-11-28 00:00:00 +0000
committerTomasz Miąsko <tomasz.miasko@gmail.com>2023-11-28 21:11:24 +0100
commit5161b22143bf9a726cfd69d19bef11552d0ed519 (patch)
treefc3a4ebf1c4fa689eff178e84cdddc79fc8b7013
parent5facb422f8a5a61df515572fe79b02433639d565 (diff)
downloadrust-5161b22143bf9a726cfd69d19bef11552d0ed519.tar.gz
rust-5161b22143bf9a726cfd69d19bef11552d0ed519.zip
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.
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs10
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs6
-rw-r--r--tests/ui/coroutine/auxiliary/unwind-aux.rs11
-rw-r--r--tests/ui/coroutine/unwind-abort-mix.rs13
4 files changed, 28 insertions, 12 deletions
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index 1cb1a9886a0..d626fed3275 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -51,7 +51,6 @@
 //! Otherwise it drops all the values in scope at the last suspension point.
 
 use crate::abort_unwinding_calls;
-use crate::add_call_guards;
 use crate::deref_separator::deref_finder;
 use crate::errors;
 use crate::pass_manager as pm;
@@ -1168,18 +1167,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, &add_call_guards::CriticalCallEdges],
-        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 f24a2d07e49..fba73d5195b 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 00000000000..215d6769116
--- /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<T>(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 00000000000..869b3e4f433
--- /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());
+}