forked from OSchip/llvm-project
[coroutines] Per latest wording paper, co_* are no longer permitted in any
unevaluated operands. llvm-svn: 253641
This commit is contained in:
parent
2dfc3b8be5
commit
744b224bb5
|
@ -7960,6 +7960,8 @@ def note_declared_coroutine_here : Note<
|
||||||
"'%select{co_await|co_yield|co_return}0' here">;
|
"'%select{co_await|co_yield|co_return}0' here">;
|
||||||
def err_coroutine_objc_method : Error<
|
def err_coroutine_objc_method : Error<
|
||||||
"Objective-C methods as coroutines are not yet supported">;
|
"Objective-C methods as coroutines are not yet supported">;
|
||||||
|
def err_coroutine_unevaluated_context : Error<
|
||||||
|
"'%0' cannot be used in an unevaluated context">;
|
||||||
def err_coroutine_outside_function : Error<
|
def err_coroutine_outside_function : Error<
|
||||||
"'%0' cannot be used outside a function">;
|
"'%0' cannot be used outside a function">;
|
||||||
def err_coroutine_ctor_dtor : Error<
|
def err_coroutine_ctor_dtor : Error<
|
||||||
|
|
|
@ -99,10 +99,11 @@ static QualType lookupPromiseType(Sema &S, const FunctionProtoType *FnType,
|
||||||
/// Check that this is a context in which a coroutine suspension can appear.
|
/// Check that this is a context in which a coroutine suspension can appear.
|
||||||
static FunctionScopeInfo *
|
static FunctionScopeInfo *
|
||||||
checkCoroutineContext(Sema &S, SourceLocation Loc, StringRef Keyword) {
|
checkCoroutineContext(Sema &S, SourceLocation Loc, StringRef Keyword) {
|
||||||
// 'co_await' and 'co_yield' are permitted in unevaluated operands.
|
// 'co_await' and 'co_yield' are not permitted in unevaluated operands.
|
||||||
// FIXME: Not in 'noexcept'.
|
if (S.isUnevaluatedContext()) {
|
||||||
if (S.isUnevaluatedContext())
|
S.Diag(Loc, diag::err_coroutine_unevaluated_context) << Keyword;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// Any other usage must be within a function.
|
// Any other usage must be within a function.
|
||||||
auto *FD = dyn_cast<FunctionDecl>(S.CurContext);
|
auto *FD = dyn_cast<FunctionDecl>(S.CurContext);
|
||||||
|
@ -206,11 +207,12 @@ ExprResult Sema::ActOnCoawaitExpr(Scope *S, SourceLocation Loc, Expr *E) {
|
||||||
}
|
}
|
||||||
ExprResult Sema::BuildCoawaitExpr(SourceLocation Loc, Expr *E) {
|
ExprResult Sema::BuildCoawaitExpr(SourceLocation Loc, Expr *E) {
|
||||||
auto *Coroutine = checkCoroutineContext(*this, Loc, "co_await");
|
auto *Coroutine = checkCoroutineContext(*this, Loc, "co_await");
|
||||||
|
if (!Coroutine)
|
||||||
|
return ExprError();
|
||||||
|
|
||||||
if (E->getType()->isDependentType()) {
|
if (E->getType()->isDependentType()) {
|
||||||
Expr *Res = new (Context) CoawaitExpr(Loc, Context.DependentTy, E);
|
Expr *Res = new (Context) CoawaitExpr(Loc, Context.DependentTy, E);
|
||||||
if (Coroutine)
|
Coroutine->CoroutineStmts.push_back(Res);
|
||||||
Coroutine->CoroutineStmts.push_back(Res);
|
|
||||||
return Res;
|
return Res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,8 +232,7 @@ ExprResult Sema::BuildCoawaitExpr(SourceLocation Loc, Expr *E) {
|
||||||
|
|
||||||
Expr *Res = new (Context) CoawaitExpr(Loc, E, RSS.Results[0], RSS.Results[1],
|
Expr *Res = new (Context) CoawaitExpr(Loc, E, RSS.Results[0], RSS.Results[1],
|
||||||
RSS.Results[2]);
|
RSS.Results[2]);
|
||||||
if (Coroutine)
|
Coroutine->CoroutineStmts.push_back(Res);
|
||||||
Coroutine->CoroutineStmts.push_back(Res);
|
|
||||||
return Res;
|
return Res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,11 +245,12 @@ ExprResult Sema::ActOnCoyieldExpr(Scope *S, SourceLocation Loc, Expr *E) {
|
||||||
}
|
}
|
||||||
ExprResult Sema::BuildCoyieldExpr(SourceLocation Loc, Expr *E) {
|
ExprResult Sema::BuildCoyieldExpr(SourceLocation Loc, Expr *E) {
|
||||||
auto *Coroutine = checkCoroutineContext(*this, Loc, "co_yield");
|
auto *Coroutine = checkCoroutineContext(*this, Loc, "co_yield");
|
||||||
|
if (!Coroutine)
|
||||||
|
return ExprError();
|
||||||
|
|
||||||
// FIXME: Build await_* calls.
|
// FIXME: Build await_* calls.
|
||||||
Expr *Res = new (Context) CoyieldExpr(Loc, Context.VoidTy, E);
|
Expr *Res = new (Context) CoyieldExpr(Loc, Context.VoidTy, E);
|
||||||
if (Coroutine)
|
Coroutine->CoroutineStmts.push_back(Res);
|
||||||
Coroutine->CoroutineStmts.push_back(Res);
|
|
||||||
return Res;
|
return Res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,11 +259,12 @@ StmtResult Sema::ActOnCoreturnStmt(SourceLocation Loc, Expr *E) {
|
||||||
}
|
}
|
||||||
StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, Expr *E) {
|
StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, Expr *E) {
|
||||||
auto *Coroutine = checkCoroutineContext(*this, Loc, "co_return");
|
auto *Coroutine = checkCoroutineContext(*this, Loc, "co_return");
|
||||||
|
if (!Coroutine)
|
||||||
|
return StmtError();
|
||||||
|
|
||||||
// FIXME: Build return_* calls.
|
// FIXME: Build return_* calls.
|
||||||
Stmt *Res = new (Context) CoreturnStmt(Loc, E);
|
Stmt *Res = new (Context) CoreturnStmt(Loc, E);
|
||||||
if (Coroutine)
|
Coroutine->CoroutineStmts.push_back(Res);
|
||||||
Coroutine->CoroutineStmts.push_back(Res);
|
|
||||||
return Res;
|
return Res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,8 +78,17 @@ struct CtorDtor {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr void constexpr_coroutine() { // expected-error {{never produces a constant expression}}
|
void unevaluated() {
|
||||||
co_yield 0; // expected-error {{'co_yield' cannot be used in a constexpr function}} expected-note {{subexpression}}
|
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 *, ...) {
|
void varargs_coroutine(const char *, ...) {
|
||||||
|
|
Loading…
Reference in New Issue