r253817 - [coroutines] Check for overload sets in co_yield / co_return operands being resolved by a call to yield_value / return_value before rejecting them.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Sat Nov 21 23:33:28 PST 2015


Author: rsmith
Date: Sun Nov 22 01:33:28 2015
New Revision: 253817

URL: http://llvm.org/viewvc/llvm-project?rev=253817&view=rev
Log:
[coroutines] Check for overload sets in co_yield / co_return operands being resolved by a call to yield_value / return_value before rejecting them.

Modified:
    cfe/trunk/lib/Sema/SemaCoroutine.cpp
    cfe/trunk/test/SemaCXX/coroutines.cpp

Modified: cfe/trunk/lib/Sema/SemaCoroutine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCoroutine.cpp?rev=253817&r1=253816&r2=253817&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCoroutine.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCoroutine.cpp Sun Nov 22 01:33:28 2015
@@ -52,6 +52,8 @@ static QualType lookupPromiseType(Sema &
   Args.addArgument(TemplateArgumentLoc(
       TemplateArgument(FnType->getReturnType()),
       S.Context.getTrivialTypeSourceInfo(FnType->getReturnType(), Loc)));
+  // FIXME: If the function is a non-static member function, add the type
+  // of the implicit object parameter before the formal parameters.
   for (QualType T : FnType->getParamTypes())
     Args.addArgument(TemplateArgumentLoc(
         TemplateArgument(T), S.Context.getTrivialTypeSourceInfo(T, Loc)));
@@ -270,12 +272,6 @@ static ExprResult buildPromiseCall(Sema
 }
 
 ExprResult Sema::ActOnCoyieldExpr(Scope *S, SourceLocation Loc, Expr *E) {
-  if (E->getType()->isPlaceholderType()) {
-    ExprResult R = CheckPlaceholderExpr(E);
-    if (R.isInvalid()) return ExprError();
-    E = R.get();
-  }
-
   auto *Coroutine = checkCoroutineContext(*this, Loc, "co_yield");
   if (!Coroutine)
     return ExprError();
@@ -330,16 +326,17 @@ StmtResult Sema::ActOnCoreturnStmt(Sourc
   return BuildCoreturnStmt(Loc, E);
 }
 StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, Expr *E) {
-  if (E && E->getType()->isPlaceholderType()) {
+  auto *Coroutine = checkCoroutineContext(*this, Loc, "co_return");
+  if (!Coroutine)
+    return StmtError();
+
+  if (E && E->getType()->isPlaceholderType() &&
+      !E->getType()->isSpecificPlaceholderType(BuiltinType::Overload)) {
     ExprResult R = CheckPlaceholderExpr(E);
     if (R.isInvalid()) return StmtError();
     E = R.get();
   }
 
-  auto *Coroutine = checkCoroutineContext(*this, Loc, "co_return");
-  if (!Coroutine)
-    return StmtError();
-
   // FIXME: If the operand is a reference to a variable that's about to go out
   // ot scope, we should treat the operand as an xvalue for this overload
   // resolution.

Modified: cfe/trunk/test/SemaCXX/coroutines.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/coroutines.cpp?rev=253817&r1=253816&r2=253817&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/coroutines.cpp (original)
+++ cfe/trunk/test/SemaCXX/coroutines.cpp Sun Nov 22 01:33:28 2015
@@ -49,11 +49,11 @@ struct yielded_thing { const char *p; sh
 struct not_awaitable {};
 
 struct promise {
-  awaitable yield_value(int); // expected-note {{candidate}}
-  awaitable yield_value(yielded_thing); // expected-note {{candidate}}
-  not_awaitable yield_value(void()); // expected-note {{candidate}}
+  awaitable yield_value(int); // expected-note 2{{candidate}}
+  awaitable yield_value(yielded_thing); // expected-note 2{{candidate}}
+  not_awaitable yield_value(void()); // expected-note 2{{candidate}}
   void return_void();
-  void return_value(int); // expected-note {{here}}
+  void return_value(int); // expected-note 2{{here}}
 };
 
 void yield() {
@@ -159,17 +159,37 @@ namespace dependent_operator_co_await_lo
   template void await_template_2(outer);
 }
 
+struct yield_fn_tag {};
+template<> struct std::coroutine_traits<void, yield_fn_tag> {
+  struct promise_type {
+    // FIXME: add an await_transform overload for functions
+    awaitable yield_value(int());
+    void return_value(int());
+  };
+};
+
 namespace placeholder {
-  awaitable f(), f(int); // expected-note 2{{possible target}}
-  int g(), g(int); // expected-note 4{{possible target}}
+  awaitable f(), f(int); // expected-note 4{{possible target}}
+  int g(), g(int); // expected-note 2{{candidate}}
   void x() {
     co_await f; // expected-error {{reference to overloaded function}}
   }
   void y() {
-    co_yield g; // expected-error {{reference to overloaded function}}
+    co_yield g; // expected-error {{no matching member function for call to 'yield_value'}}
   }
   void z() {
     co_await a;
-    co_return g; // expected-error {{reference to overloaded function}}
+    co_return g; // expected-error {{address of overloaded function 'g' does not match required type 'int'}}
+  }
+
+  void x(yield_fn_tag) {
+    co_await f; // expected-error {{reference to overloaded function}}
+  }
+  void y(yield_fn_tag) {
+    co_yield g;
+  }
+  void z(yield_fn_tag) {
+    co_await a;
+    co_return g;
   }
 }




More information about the cfe-commits mailing list