[Coroutines] Do not evaluate InitListExpr of a co_return
Differential Revision: https://reviews.llvm.org/D76118
This commit is contained in:
parent
0eba5dc80f
commit
53c2e10fb8
|
@ -275,9 +275,9 @@ RValue CodeGenFunction::EmitCoyieldExpr(const CoyieldExpr &E,
|
||||||
void CodeGenFunction::EmitCoreturnStmt(CoreturnStmt const &S) {
|
void CodeGenFunction::EmitCoreturnStmt(CoreturnStmt const &S) {
|
||||||
++CurCoro.Data->CoreturnCount;
|
++CurCoro.Data->CoreturnCount;
|
||||||
const Expr *RV = S.getOperand();
|
const Expr *RV = S.getOperand();
|
||||||
if (RV && RV->getType()->isVoidType()) {
|
if (RV && RV->getType()->isVoidType() && !isa<InitListExpr>(RV)) {
|
||||||
// Make sure to evaluate the expression of a co_return with a void
|
// Make sure to evaluate the non initlist expression of a co_return
|
||||||
// expression for side effects.
|
// with a void expression for side effects.
|
||||||
RunCleanupsScope cleanupScope(*this);
|
RunCleanupsScope cleanupScope(*this);
|
||||||
EmitIgnoredExpr(RV);
|
EmitIgnoredExpr(RV);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 <typename a>
|
||||||
|
struct b { b(int, a); };
|
||||||
|
template <typename, typename = int>
|
||||||
|
struct c {};
|
||||||
|
namespace experimental {
|
||||||
|
template <typename d>
|
||||||
|
struct coroutine_traits : d {};
|
||||||
|
template <typename = void>
|
||||||
|
struct coroutine_handle;
|
||||||
|
template <>
|
||||||
|
struct coroutine_handle<> {};
|
||||||
|
template <typename>
|
||||||
|
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 <typename ag>
|
||||||
|
auto ah(ag) { return ag().ah(0); }
|
||||||
|
template <typename>
|
||||||
|
struct f;
|
||||||
|
struct g {
|
||||||
|
struct h {
|
||||||
|
int await_ready();
|
||||||
|
template <typename al>
|
||||||
|
void await_suspend(std::experimental::coroutine_handle<al>);
|
||||||
|
void await_resume();
|
||||||
|
};
|
||||||
|
std::experimental::e initial_suspend();
|
||||||
|
h final_suspend();
|
||||||
|
template <typename ag>
|
||||||
|
auto await_transform(ag) { return ah(ag()); }
|
||||||
|
};
|
||||||
|
struct j : g {
|
||||||
|
f<std::b<std::c<int, int>>> get_return_object();
|
||||||
|
void return_value(std::b<std::c<int, int>>);
|
||||||
|
void unhandled_exception();
|
||||||
|
};
|
||||||
|
struct k {
|
||||||
|
k(std::experimental::coroutine_handle<>);
|
||||||
|
int await_ready();
|
||||||
|
};
|
||||||
|
template <typename am>
|
||||||
|
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 <typename am, typename av, typename aw>
|
||||||
|
auto ax(std::c<am, av>, aw) -> f<std::c<int, aw>>;
|
||||||
|
template <typename>
|
||||||
|
struct J { static f<std::b<std::c<int, int>>> bo(); };
|
||||||
|
// CHECK-LABEL: _ZN1JIiE2boEv(
|
||||||
|
template <typename bc>
|
||||||
|
f<std::b<std::c<int, int>>> J<bc>::bo() {
|
||||||
|
std::c<int> bu;
|
||||||
|
int bw(0);
|
||||||
|
// CHECK: void @_ZN1j12return_valueESt1bISt1cIiiEE(%struct.j* %__promise)
|
||||||
|
co_return{0, co_await ax(bu, bw)};
|
||||||
|
}
|
||||||
|
void bh() {
|
||||||
|
auto cn = [] { J<int>::bo; };
|
||||||
|
cn();
|
||||||
|
}
|
Loading…
Reference in New Issue