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

llvm-svn: 253817
diff --git a/clang/test/SemaCXX/coroutines.cpp b/clang/test/SemaCXX/coroutines.cpp
index 85cc919..af50eab 100644
--- a/clang/test/SemaCXX/coroutines.cpp
+++ b/clang/test/SemaCXX/coroutines.cpp
@@ -49,11 +49,11 @@
 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 @@
   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;
   }
 }