https://github.com/yuxuanchen1997 updated https://github.com/llvm/llvm-project/pull/73073
>From f782f36c42f9bc1246837bf7ff2142919794580b Mon Sep 17 00:00:00 2001 From: Yuxuan Chen <y...@meta.com> Date: Tue, 21 Nov 2023 19:06:31 -0800 Subject: [PATCH 1/2] [Clang][coro] Fix crash on emitting init suspend if the return type of await_resume() is not trivially destructible --- clang/lib/CodeGen/CGCoroutine.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/clang/lib/CodeGen/CGCoroutine.cpp b/clang/lib/CodeGen/CGCoroutine.cpp index 7e449d5af3423cf..aaf122c0f83bc47 100644 --- a/clang/lib/CodeGen/CGCoroutine.cpp +++ b/clang/lib/CodeGen/CGCoroutine.cpp @@ -245,6 +245,15 @@ static LValueOrRValue emitSuspendExpression(CodeGenFunction &CGF, CGCoroData &Co FPOptionsOverride(), Loc, Loc); TryStmt = CXXTryStmt::Create(CGF.getContext(), Loc, TryBody, Catch); CGF.EnterCXXTryStmt(*TryStmt); + CGF.EmitStmt(TryBody); + // We don't use EmitCXXTryStmt here. We need to store to ResumeEHVar that + // doesn't exist in the body. + Builder.CreateFlagStore(false, Coro.ResumeEHVar); + CGF.ExitCXXTryStmt(*TryStmt); + LValueOrRValue Res; + // We are not supposed to obtain the value from init suspend await_resume(). + Res.RV = RValue::getIgnored(); + return Res; } LValueOrRValue Res; @@ -253,11 +262,6 @@ static LValueOrRValue emitSuspendExpression(CodeGenFunction &CGF, CGCoroData &Co else Res.RV = CGF.EmitAnyExpr(S.getResumeExpr(), aggSlot, ignoreResult); - if (TryStmt) { - Builder.CreateFlagStore(false, Coro.ResumeEHVar); - CGF.ExitCXXTryStmt(*TryStmt); - } - return Res; } >From 9f98b9d0b812b1027bfc4d963b353feeac36834b Mon Sep 17 00:00:00 2001 From: Yuxuan Chen <y...@meta.com> Date: Tue, 21 Nov 2023 19:35:10 -0800 Subject: [PATCH 2/2] add test case for the previously crashing case --- .../coro-init-await-nontrivial-return.cpp | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 clang/test/CodeGenCoroutines/coro-init-await-nontrivial-return.cpp diff --git a/clang/test/CodeGenCoroutines/coro-init-await-nontrivial-return.cpp b/clang/test/CodeGenCoroutines/coro-init-await-nontrivial-return.cpp new file mode 100644 index 000000000000000..78fc88a071d5c74 --- /dev/null +++ b/clang/test/CodeGenCoroutines/coro-init-await-nontrivial-return.cpp @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -std=c++20 -triple=x86_64-- -emit-llvm -fcxx-exceptions \ +// RUN: -disable-llvm-passes %s -o - | FileCheck %s + +#include "Inputs/coroutine.h" + +struct NontrivialType { + ~NontrivialType() {} +}; + +struct Task { + struct promise_type; + using handle_type = std::coroutine_handle<promise_type>; + + struct initial_suspend_awaiter { + bool await_ready() { + return false; + } + + void await_suspend(handle_type h) {} + + // Nontrivial type caused crash! + NontrivialType await_resume() noexcept { + return {}; + } + }; + + struct promise_type { + void return_void() {} + void unhandled_exception() {} + initial_suspend_awaiter initial_suspend() { return {}; } + std::suspend_never final_suspend() noexcept { return {}; } + Task get_return_object() { + return Task{handle_type::from_promise(*this)}; + } + }; + + handle_type handler; +}; + +Task coro_create() { + co_return; +} + +// CHECK-LABEL: define{{.*}} ptr @_Z11coro_createv( +// CHECK: init.ready: +// CHECK-NEXT: store i1 true, ptr {{.*}} +// CHECK-NEXT: call void @_ZN4Task23initial_suspend_awaiter12await_resumeEv( +// CHECK-NEXT: call void @_ZN14NontrivialTypeD1Ev( +// CHECK-NEXT: store i1 false, ptr {{.*}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits