/// Check that this is a context in which a coroutine suspension can appear.
static FunctionScopeInfo *
checkCoroutineContext(Sema &S, SourceLocation Loc, StringRef Keyword) {
- // 'co_await' and 'co_yield' are permitted in unevaluated operands.
- // FIXME: Not in 'noexcept'.
- if (S.isUnevaluatedContext())
+ // 'co_await' and 'co_yield' are not permitted in unevaluated operands.
+ if (S.isUnevaluatedContext()) {
+ S.Diag(Loc, diag::err_coroutine_unevaluated_context) << Keyword;
return nullptr;
+ }
// Any other usage must be within a function.
auto *FD = dyn_cast<FunctionDecl>(S.CurContext);
}
ExprResult Sema::BuildCoawaitExpr(SourceLocation Loc, Expr *E) {
auto *Coroutine = checkCoroutineContext(*this, Loc, "co_await");
+ if (!Coroutine)
+ return ExprError();
if (E->getType()->isDependentType()) {
Expr *Res = new (Context) CoawaitExpr(Loc, Context.DependentTy, E);
- if (Coroutine)
- Coroutine->CoroutineStmts.push_back(Res);
+ Coroutine->CoroutineStmts.push_back(Res);
return Res;
}
Expr *Res = new (Context) CoawaitExpr(Loc, E, RSS.Results[0], RSS.Results[1],
RSS.Results[2]);
- if (Coroutine)
- Coroutine->CoroutineStmts.push_back(Res);
+ Coroutine->CoroutineStmts.push_back(Res);
return Res;
}
}
ExprResult Sema::BuildCoyieldExpr(SourceLocation Loc, Expr *E) {
auto *Coroutine = checkCoroutineContext(*this, Loc, "co_yield");
+ if (!Coroutine)
+ return ExprError();
// FIXME: Build await_* calls.
Expr *Res = new (Context) CoyieldExpr(Loc, Context.VoidTy, E);
- if (Coroutine)
- Coroutine->CoroutineStmts.push_back(Res);
+ Coroutine->CoroutineStmts.push_back(Res);
return Res;
}
}
StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, Expr *E) {
auto *Coroutine = checkCoroutineContext(*this, Loc, "co_return");
+ if (!Coroutine)
+ return StmtError();
// FIXME: Build return_* calls.
Stmt *Res = new (Context) CoreturnStmt(Loc, E);
- if (Coroutine)
- Coroutine->CoroutineStmts.push_back(Res);
+ Coroutine->CoroutineStmts.push_back(Res);
return Res;
}
}
};
-constexpr void constexpr_coroutine() { // expected-error {{never produces a constant expression}}
- co_yield 0; // expected-error {{'co_yield' cannot be used in a constexpr function}} expected-note {{subexpression}}
+void unevaluated() {
+ decltype(co_await a); // expected-error {{cannot be used in an unevaluated context}}
+ sizeof(co_await a); // expected-error {{cannot be used in an unevaluated context}}
+ typeid(co_await a); // expected-error {{cannot be used in an unevaluated context}}
+ decltype(co_yield a); // expected-error {{cannot be used in an unevaluated context}}
+ sizeof(co_yield a); // expected-error {{cannot be used in an unevaluated context}}
+ typeid(co_yield a); // expected-error {{cannot be used in an unevaluated context}}
+}
+
+constexpr void constexpr_coroutine() {
+ co_yield 0; // expected-error {{'co_yield' cannot be used in a constexpr function}}
}
void varargs_coroutine(const char *, ...) {