Builder.ReturnValue = Res.get();
if (S->hasDependentPromiseType()) {
- assert(!Promise->getType()->isDependentType() &&
- "the promise type must no longer be dependent");
- assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
- !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
- "these nodes should not have been built yet");
- if (!Builder.buildDependentStatements())
- return StmtError();
+ // PR41909: We may find a generic coroutine lambda definition within a
+ // template function that is being instantiated. In this case, the lambda
+ // will have a dependent promise type, until it is used in an expression
+ // that creates an instantiation with a non-dependent promise type. We
+ // should not assert or build coroutine dependent statements for such a
+ // generic lambda.
+ auto *MD = dyn_cast_or_null<CXXMethodDecl>(FD);
+ if (!MD || !MD->getParent()->isGenericLambda()) {
+ assert(!Promise->getType()->isDependentType() &&
+ "the promise type must no longer be dependent");
+ assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
+ !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
+ "these nodes should not have been built yet");
+ if (!Builder.buildDependentStatements())
+ return StmtError();
+ }
} else {
if (auto *OnFallthrough = S->getFallthroughHandler()) {
StmtResult Res = getDerived().TransformStmt(OnFallthrough);
co_await 42;
}
+template<typename T> void ok_generic_lambda_coawait_PR41909() {
+ [](auto& arg) -> coro<good_promise_1> { // expected-warning {{expression result unused}}
+ co_await 12;
+ };
+ [](auto &arg) -> coro<good_promise_1> {
+ co_await 24;
+ }("argument");
+}
+template void ok_generic_lambda_coawait_PR41909<int>(); // expected-note {{in instantiation of function template specialization 'ok_generic_lambda_coawait_PR41909<int>' requested here}}
+
template<> struct std::experimental::coroutine_traits<int, int, const char**>
{ using promise_type = promise; };