llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-codegen Author: Yuxuan Chen (yuxuanchen1997) <details> <summary>Changes</summary> This change aims to fix an ICE in issue https://github.com/llvm/llvm-project/issues/63803 The crash happens in `ExitCXXTryStmt` because `EmitAnyExpr()` adds additional cleanup to the `EHScopeStack`. This messes up the assumption in `ExitCXXTryStmt` that the top of the stack should be a `EHCatchScope`. However, since we never read a value returned from `await_resume()` of an init suspend, we can skip the part that builds this `RValue`. --- Full diff: https://github.com/llvm/llvm-project/pull/73073.diff 2 Files Affected: - (modified) clang/lib/CodeGen/CGCoroutine.cpp (+9-5) - (added) clang/test/CodeGenCoroutines/coro-init-await-nontrivial-return.cpp (+49) ``````````diff 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; } 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 {{.*}} `````````` </details> https://github.com/llvm/llvm-project/pull/73073 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits