https://github.com/yuxuanchen1997 updated https://github.com/llvm/llvm-project/pull/73073
>From e7d1ae077d7d301094b663166cc0c14c706d2110 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/3] [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 e11b48867b2f02a095d043d57cf7830702f47ed6 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/3] add test case for the previously crashing case --- .../coro-init-await-nontrivial-return.cpp | 46 +++++++++++++++++++ 1 file changed, 46 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..c4b8da327f5c140 --- /dev/null +++ b/clang/test/CodeGenCoroutines/coro-init-await-nontrivial-return.cpp @@ -0,0 +1,46 @@ +// 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) {} + + NontrivialType await_resume() { 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 {{.*}} >From 231760360962cf980f06f2b83d1467fd2c9f1078 Mon Sep 17 00:00:00 2001 From: Yuxuan Chen <y...@meta.com> Date: Tue, 21 Nov 2023 19:52:34 -0800 Subject: [PATCH 3/3] Add release note entry --- clang/docs/ReleaseNotes.rst | 4 ++++ clang/lib/CodeGen/CGCoroutine.cpp | 2 ++ 2 files changed, 6 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 157afd9e8629152..9f9f83c673b7ba7 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -592,6 +592,7 @@ Bug Fixes in This Version - Clang now properly diagnoses use of stand-alone OpenMP directives after a label (including ``case`` or ``default`` labels). + Before: .. code-block:: c++ @@ -610,6 +611,9 @@ Bug Fixes in This Version inside a lambda. (`#61460 <https://github.com/llvm/llvm-project/issues/61460>`_) - Fix crash during instantiation of some class template specializations within class templates. Fixes (`#70375 <https://github.com/llvm/llvm-project/issues/70375>`_) +- Fix crash during code generation of C++ coroutine initial suspend when the + return type of await_resume is not trivially destructible. + Fixes (`#63803 <https://github.com/llvm/llvm-project/issues/63803>`_) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/CodeGen/CGCoroutine.cpp b/clang/lib/CodeGen/CGCoroutine.cpp index aaf122c0f83bc47..ec30c974253d95f 100644 --- a/clang/lib/CodeGen/CGCoroutine.cpp +++ b/clang/lib/CodeGen/CGCoroutine.cpp @@ -130,6 +130,8 @@ static SmallString<32> buildSuspendPrefixStr(CGCoroData &Coro, AwaitKind Kind) { } static bool memberCallExpressionCanThrow(const Expr *E) { + E->dump(); + std::terminate(); if (const auto *CE = dyn_cast<CXXMemberCallExpr>(E)) if (const auto *Proto = CE->getMethodDecl()->getType()->getAs<FunctionProtoType>()) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits