]> granicus.if.org Git - clang/commitdiff
[coroutines] Per latest wording paper, co_* are no longer permitted in any
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 20 Nov 2015 02:54:01 +0000 (02:54 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 20 Nov 2015 02:54:01 +0000 (02:54 +0000)
unevaluated operands.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@253641 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaCoroutine.cpp
test/SemaCXX/coroutines.cpp

index 22d859e7775024b153295a4914af548ff11ff227..78ee1cac02ef9ed065f2557355ace28174b6fac1 100644 (file)
@@ -7960,6 +7960,8 @@ def note_declared_coroutine_here : Note<
   "'%select{co_await|co_yield|co_return}0' here">;
 def err_coroutine_objc_method : Error<
   "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<
   "'%0' cannot be used outside a function">;
 def err_coroutine_ctor_dtor : Error<
index 210f30e2a4ee32aaba0ff1d424241acb0643e5fc..b4ba6e385b1ee468077c8d13df49a1277d9bf541 100644 (file)
@@ -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.
 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);
@@ -206,11 +207,12 @@ ExprResult Sema::ActOnCoawaitExpr(Scope *S, SourceLocation Loc, Expr *E) {
 }
 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;
   }
 
@@ -230,8 +232,7 @@ ExprResult Sema::BuildCoawaitExpr(SourceLocation Loc, Expr *E) {
 
   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;
 }
 
@@ -244,11 +245,12 @@ ExprResult Sema::ActOnCoyieldExpr(Scope *S, SourceLocation Loc, Expr *E) {
 }
 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;
 }
 
@@ -257,11 +259,12 @@ StmtResult Sema::ActOnCoreturnStmt(SourceLocation Loc, Expr *E) {
 }
 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;
 }
 
index c82302c3c0708063657d0547aa572471b49bc9ae..6ca8d314f94dd503f9565db53a491fc64d8089f1 100644 (file)
@@ -78,8 +78,17 @@ struct CtorDtor {
   }
 };
 
-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 *, ...) {