diff --git a/clang/lib/CodeGen/CGCoroutine.cpp b/clang/lib/CodeGen/CGCoroutine.cpp --- a/clang/lib/CodeGen/CGCoroutine.cpp +++ b/clang/lib/CodeGen/CGCoroutine.cpp @@ -275,9 +275,9 @@ void CodeGenFunction::EmitCoreturnStmt(CoreturnStmt const &S) { ++CurCoro.Data->CoreturnCount; const Expr *RV = S.getOperand(); - if (RV && RV->getType()->isVoidType()) { - // Make sure to evaluate the expression of a co_return with a void - // expression for side effects. + if (RV && RV->getType()->isVoidType() && !isa(RV)) { + // Make sure to evaluate the non initlist expression of a co_return + // with a void expression for side effects. RunCleanupsScope cleanupScope(*this); EmitIgnoredExpr(RV); } diff --git a/clang/test/CodeGenCoroutines/coro-return-voidtype-initlist.cpp b/clang/test/CodeGenCoroutines/coro-return-voidtype-initlist.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenCoroutines/coro-return-voidtype-initlist.cpp @@ -0,0 +1,81 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcoroutines-ts -std=c++1z -emit-llvm %s -o - -disable-llvm-passes | FileCheck %s + +namespace std { +template +struct b { b(int, a); }; +template +struct c {}; +namespace experimental { +template +struct coroutine_traits : d {}; +template +struct coroutine_handle; +template <> +struct coroutine_handle<> {}; +template +struct coroutine_handle : coroutine_handle<> { + static coroutine_handle from_address(void *); +}; +struct e { + int await_ready(); + void await_suspend(coroutine_handle<>); + void await_resume(); +}; +} // namespace experimental +} // namespace std +template +auto ah(ag) { return ag().ah(0); } +template +struct f; +struct g { + struct h { + int await_ready(); + template + void await_suspend(std::experimental::coroutine_handle); + void await_resume(); + }; + std::experimental::e initial_suspend(); + h final_suspend(); + template + auto await_transform(ag) { return ah(ag()); } +}; +struct j : g { + f>> get_return_object(); + void return_value(std::b>); + void unhandled_exception(); +}; +struct k { + k(std::experimental::coroutine_handle<>); + int await_ready(); +}; +template +struct f { + using promise_type = j; + std::experimental::coroutine_handle<> ar; + struct l : k { + using at = k; + l(std::experimental::coroutine_handle<> m) : at(m) {} + void await_suspend(std::experimental::coroutine_handle<>); + }; + struct n : l { + n(std::experimental::coroutine_handle<> m) : l(m) {} + am await_resume(); + }; + auto ah(int) { return n(ar); } +}; +template +auto ax(std::c, aw) -> f>; +template +struct J { static f>> bo(); }; +// CHECK-LABEL: _ZN1JIiE2boEv( +template +f>> J::bo() { + std::c bu; + int bw(0); + // CHECK: void @_ZN1j12return_valueESt1bISt1cIiiEE(%struct.j* %__promise) + co_return{0, co_await ax(bu, bw)}; +} +void bh() { + auto cn = [] { J::bo; }; + cn(); +}