From cec8e09edf55fbf474c4414e3fec26d85c7869ff Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Wed, 28 Jun 2023 16:05:17 +0100 Subject: [PATCH] Run `AbortUnwindingCalls` after generator transform --- compiler/rustc_mir_transform/src/generator.rs | 16 +++++++++++++ ...await.a-{closure#0}.generator_resume.0.mir | 2 +- ...await.b-{closure#0}.generator_resume.0.mir | 2 +- tests/run-make/panic-abort-eh_frame/Makefile | 2 +- tests/run-make/panic-abort-eh_frame/foo.rs | 24 +++++++++++++++++++ 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 797a1a86846..2bd759ab1e5 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -50,8 +50,10 @@ //! For generators with state 1 (returned) and state 2 (poisoned) it does nothing. //! Otherwise it drops all the values in scope at the last suspension point. +use crate::abort_unwinding_calls; use crate::deref_separator::deref_finder; use crate::errors; +use crate::pass_manager as pm; use crate::simplify; use crate::MirPass; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; @@ -64,6 +66,7 @@ use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::dump_mir; use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc_middle::mir::*; +use rustc_middle::ty::InstanceDef; use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt}; use rustc_middle::ty::{GeneratorArgs, GenericArgsRef}; use rustc_mir_dataflow::impls::{ @@ -1147,6 +1150,17 @@ fn create_generator_drop_shim<'tcx>( // unrelated code from the resume part of the function simplify::remove_dead_blocks(tcx, &mut body); + // Update the body's def to become the drop glue. + let drop_in_place = tcx.require_lang_item(LangItem::DropInPlace, None); + body.source.instance = InstanceDef::DropGlue(drop_in_place, Some(gen_ty)); + + pm::run_passes_no_validate( + tcx, + &mut body, + &[&abort_unwinding_calls::AbortUnwindingCalls], + None, + ); + dump_mir(tcx, false, "generator_drop", &0, &body, |_, _| Ok(())); body @@ -1317,6 +1331,8 @@ fn create_generator_resume_function<'tcx>( // unrelated code from the drop part of the function simplify::remove_dead_blocks(tcx, body); + pm::run_passes_no_validate(tcx, body, &[&abort_unwinding_calls::AbortUnwindingCalls], None); + dump_mir(tcx, false, "generator_resume", &0, body, |_, _| Ok(())); } diff --git a/tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir b/tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir index 074ebddf78b..9be5b8509c7 100644 --- a/tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir +++ b/tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir @@ -30,7 +30,7 @@ fn a::{closure#0}(_1: Pin<&mut [async fn body@$DIR/async_await.rs:11:14: 11:16]> } bb2: { - assert(const false, "`async fn` resumed after completion") -> [success: bb2, unwind continue]; + assert(const false, "`async fn` resumed after completion") -> [success: bb2, unwind unreachable]; } bb3: { diff --git a/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir b/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir index f774f32eb23..80ac92d59f3 100644 --- a/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir +++ b/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir @@ -310,7 +310,7 @@ fn b::{closure#0}(_1: Pin<&mut [async fn body@$DIR/async_await.rs:14:18: 17:2]>, } bb28: { - assert(const false, "`async fn` resumed after completion") -> [success: bb28, unwind continue]; + assert(const false, "`async fn` resumed after completion") -> [success: bb28, unwind unreachable]; } bb29: { diff --git a/tests/run-make/panic-abort-eh_frame/Makefile b/tests/run-make/panic-abort-eh_frame/Makefile index 1cb7bf575cb..7020455b742 100644 --- a/tests/run-make/panic-abort-eh_frame/Makefile +++ b/tests/run-make/panic-abort-eh_frame/Makefile @@ -6,5 +6,5 @@ include ../tools.mk all: - $(RUSTC) foo.rs --crate-type=lib --emit=obj=$(TMPDIR)/foo.o -Cpanic=abort + $(RUSTC) foo.rs --crate-type=lib --emit=obj=$(TMPDIR)/foo.o -Cpanic=abort --edition 2021 -Z validate-mir objdump --dwarf=frames $(TMPDIR)/foo.o | $(CGREP) -v 'DW_CFA' diff --git a/tests/run-make/panic-abort-eh_frame/foo.rs b/tests/run-make/panic-abort-eh_frame/foo.rs index e1853529455..e2274d469e7 100644 --- a/tests/run-make/panic-abort-eh_frame/foo.rs +++ b/tests/run-make/panic-abort-eh_frame/foo.rs @@ -1,5 +1,13 @@ #![no_std] +use core::future::Future; + +pub struct NeedsDrop; + +impl Drop for NeedsDrop { + fn drop(&mut self) {} +} + #[panic_handler] fn handler(_: &core::panic::PanicInfo<'_>) -> ! { loop {} @@ -8,3 +16,19 @@ fn handler(_: &core::panic::PanicInfo<'_>) -> ! { pub unsafe fn oops(x: *const u32) -> u32 { *x } + +pub async fn foo(_: NeedsDrop) { + async fn bar() {} + bar().await; +} + +pub fn poll_foo(x: &mut core::task::Context<'_>) { + let _g = NeedsDrop; + let mut p = core::pin::pin!(foo(NeedsDrop)); + let _ = p.as_mut().poll(x); + let _ = p.as_mut().poll(x); +} + +pub fn drop_foo() { + drop(foo(NeedsDrop)); +}