xref: /llvm-project/clang/test/SemaCXX/coroutines.cpp (revision db1375f6d907f1af34c03b5174b7e0432f615d21)
1 // This file contains references to sections of the Coroutines TS, which can be
2 // found at http://wg21.link/coroutines.
3 
4 // RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify=expected,cxx20_23,cxx23    %s -fcxx-exceptions -fexceptions -Wunused-result
5 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected,cxx14_20,cxx20_23 %s -fcxx-exceptions -fexceptions -Wunused-result
6 
7 // Run without -verify to check the order of errors we show.
8 // RUN: not %clang_cc1 -std=c++20 -fsyntax-only %s -fcxx-exceptions -fexceptions -Wunused-result 2>&1 | FileCheck %s
9 
10 void no_coroutine_traits_bad_arg_await() {
11   co_await a; // expected-error {{include <coroutine>}}
12   // expected-error@-1 {{use of undeclared identifier 'a'}}
13 }
14 
15 void no_coroutine_traits_bad_arg_yield() {
16   co_yield a; // expected-error {{include <coroutine>}}
17   // expected-error@-1 {{use of undeclared identifier 'a'}}
18 }
19 
20 
21 void no_coroutine_traits_bad_arg_return() {
22   co_return a; // expected-error {{include <coroutine>}}
23   // expected-error@-1 {{use of undeclared identifier 'a'}}
24 }
25 
26 void no_coroutine_traits() {
27   co_await 4; // expected-error {{std::coroutine_traits type was not found; include <coroutine>}}
28 }
29 
30 namespace std {
31 
32 template <class... Args>
33 struct void_t_imp {
34   using type = void;
35 };
36 template <class... Args>
37 using void_t = typename void_t_imp<Args...>::type;
38 
39 template <class T, class = void>
40 struct traits_sfinae_base {};
41 
42 template <class T>
43 struct traits_sfinae_base<T, void_t<typename T::promise_type>> {
44   using promise_type = typename T::promise_type;
45 };
46 
47 template <class Ret, class... Args>
48 struct coroutine_traits : public traits_sfinae_base<Ret> {};
49 } // end of namespace std
50 
51 template<typename Promise> struct coro {};
52 template <typename Promise, typename... Ps>
53 struct std::coroutine_traits<coro<Promise>, Ps...> {
54   using promise_type = Promise;
55 };
56 
57 struct awaitable {
58   bool await_ready() noexcept;
59   template <typename F>
60   void await_suspend(F) noexcept;
61   void await_resume() noexcept;
62 } a;
63 
64 struct suspend_always {
65   bool await_ready() noexcept { return false; }
66   template <typename F>
67   void await_suspend(F) noexcept;
68   void await_resume() noexcept {}
69 };
70 
71 struct suspend_never {
72   bool await_ready() noexcept { return true; }
73   template <typename F>
74   void await_suspend(F) noexcept;
75   void await_resume() noexcept {}
76 };
77 
78 struct auto_await_suspend {
79   bool await_ready();
80   template <typename F> auto await_suspend(F) {}
81   void await_resume();
82 };
83 
84 struct DummyVoidTag {};
85 DummyVoidTag no_specialization() { // expected-error {{this function cannot be a coroutine: 'std::coroutine_traits<DummyVoidTag>' has no member named 'promise_type'}}
86   co_await a;
87 }
88 
89 template <typename... T>
90 struct std::coroutine_traits<int, T...> {};
91 
92 int no_promise_type() { // expected-error {{this function cannot be a coroutine: 'std::coroutine_traits<int>' has no member named 'promise_type'}}
93   co_await a;
94 }
95 
96 int no_promise_type_multiple_awaits(int) { // expected-error {{this function cannot be a coroutine: 'std::coroutine_traits<int, int>' has no member named 'promise_type'}}
97   co_await a;
98   co_await a;
99 }
100 
101 template <>
102 struct std::coroutine_traits<double, double> { typedef int promise_type; };
103 double bad_promise_type(double) { // expected-error {{this function cannot be a coroutine: 'std::coroutine_traits<double, double>::promise_type' (aka 'int') is not a class}}
104   co_await a;
105 }
106 
107 template <>
108 struct std::coroutine_traits<double, int> {
109   struct promise_type {};
110 };
111 double bad_promise_type_2(int) { // expected-error {{no member named 'initial_suspend'}}
112   co_yield 0;                    // expected-error {{no member named 'yield_value' in 'std::coroutine_traits<double, int>::promise_type'}}
113 }
114 
115 struct promise; // expected-note {{forward declaration}}
116 struct promise_void;
117 struct void_tag {};
118 template <typename... T>
119 struct std::coroutine_traits<void, T...> { using promise_type = promise; };
120 template <typename... T>
121 struct std::coroutine_traits<void, void_tag, T...> { using promise_type = promise_void; };
122 
123 // FIXME: This diagnostic is terrible.
124 void undefined_promise() { // expected-error {{this function cannot be a coroutine: 'std::coroutine_traits<void>::promise_type' (aka 'promise') is an incomplete type}}
125   co_await a;
126 }
127 
128 struct yielded_thing { const char *p; short a, b; };
129 
130 struct not_awaitable {};
131 
132 struct promise {
133   void get_return_object();
134   suspend_always initial_suspend();
135   suspend_always final_suspend() noexcept;
136   awaitable yield_value(int); // expected-note 2{{candidate}}
137   awaitable yield_value(yielded_thing); // expected-note 2{{candidate}}
138   not_awaitable yield_value(void()); // expected-note 2{{candidate}}
139   void return_value(int); // expected-note 2{{here}}
140   void unhandled_exception();
141 };
142 
143 struct promise_void {
144   void get_return_object();
145   suspend_always initial_suspend();
146   suspend_always final_suspend() noexcept;
147   void return_void();
148   void unhandled_exception();
149 };
150 
151 void no_coroutine_handle() { // expected-error {{std::coroutine_handle type was not found; include <coroutine> before defining a coroutine}}
152   //expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
153   co_return 5; //expected-note {{function is a coroutine due to use of 'co_return' here}}
154 }
155 
156 namespace std {
157 template <class PromiseType = void>
158 struct coroutine_handle {
159   static coroutine_handle from_address(void *) noexcept;
160   static coroutine_handle from_promise(PromiseType &promise);
161 };
162 template <>
163 struct coroutine_handle<void> {
164   template <class PromiseType>
165   coroutine_handle(coroutine_handle<PromiseType>) noexcept;
166   static coroutine_handle from_address(void *) noexcept;
167   template <class PromiseType>
168   static coroutine_handle from_promise(PromiseType &promise);
169 };
170 } // namespace std
171 
172 void yield() {
173   co_yield 0;
174   co_yield {"foo", 1, 2};
175   co_yield {1e100}; // expected-error {{cannot be narrowed}} expected-note {{explicit cast}} expected-warning {{implicit conversion}} expected-warning {{braces around scalar}}
176   co_yield {"foo", __LONG_LONG_MAX__}; // expected-error {{cannot be narrowed}} expected-note {{explicit cast}} expected-warning {{changes value}}
177   co_yield {"foo"};
178   co_yield "foo"; // expected-error {{no matching}}
179   co_yield 1.0;
180   co_yield yield; // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
181 }
182 
183 void check_auto_await_suspend() {
184   co_await auto_await_suspend{}; // Should compile successfully.
185 }
186 
187 void coreturn(int n) {
188   co_await a;
189   if (n == 0)
190     co_return 3;
191   if (n == 1)
192     co_return {4}; // expected-warning {{braces around scalar initializer}}
193   if (n == 2)
194     co_return "foo"; // expected-error {{cannot initialize a parameter of type 'int' with an lvalue of type 'const char[4]'}}
195   co_return 42;
196 }
197 
198 template <class T>
199 void co_await_non_dependent_arg(T) {
200   co_await a;
201 }
202 template void co_await_non_dependent_arg(int);
203 
204 void mixed_yield() {
205   co_yield 0; // expected-note {{use of 'co_yield'}}
206   return; // expected-error {{not allowed in coroutine}}
207 }
208 
209 void mixed_yield_invalid() {
210   co_yield blah; // expected-error {{use of undeclared identifier}}
211   // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}}
212   return; // expected-error {{return statement not allowed in coroutine}}
213 }
214 
215 void mixed_yield_return_first(bool b) {
216   if (b) {
217     return; // expected-error {{return statement not allowed in coroutine}}
218   }
219   co_yield 0; // expected-note {{function is a coroutine due to use of 'co_yield'}}
220 }
221 
222 template<typename T>
223 void mixed_return_for_range(bool b, T t) {
224   if (b) {
225     return; // expected-error {{return statement not allowed in coroutine}}
226   }
227   for co_await (auto i : t){}; // expected-warning {{'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated}}
228   // expected-note@-1 {{function is a coroutine due to use of 'co_await'}}
229 }
230 
231 template <class T>
232 void mixed_yield_template(T) {
233   co_yield blah; // expected-error {{use of undeclared identifier}}
234   // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}}
235   return; // expected-error {{return statement not allowed in coroutine}}
236 }
237 
238 template <class T>
239 void mixed_yield_template2(T) {
240   co_yield 42;
241   // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}}
242   return; // expected-error {{return statement not allowed in coroutine}}
243 }
244 
245 template <class T>
246 void mixed_yield_template3(T v) {
247   co_yield blah(v);
248   // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}}
249   return; // expected-error {{return statement not allowed in coroutine}}
250 }
251 
252 void mixed_await() {
253   co_await a; // expected-note {{use of 'co_await'}}
254   return; // expected-error {{not allowed in coroutine}}
255 }
256 
257 void mixed_await_invalid() {
258   co_await 42; // expected-error {{'int' is not a structure or union}}
259   // expected-note@-1 {{function is a coroutine due to use of 'co_await'}}
260   return; // expected-error {{not allowed in coroutine}}
261 }
262 
263 template <class T>
264 void mixed_await_template(T) {
265   co_await 42;
266   // expected-note@-1 {{function is a coroutine due to use of 'co_await'}}
267   return; // expected-error {{not allowed in coroutine}}
268 }
269 
270 template <class T>
271 void mixed_await_template2(T v) {
272   co_await v; // expected-error {{'long' is not a structure or union}}
273   // expected-note@-1 {{function is a coroutine due to use of 'co_await'}}
274   return; // expected-error {{not allowed in coroutine}}
275 }
276 template void mixed_await_template2(long); // expected-note {{requested here}}
277 
278 void only_coreturn(void_tag) {
279   co_return; // OK
280 }
281 
282 void mixed_coreturn(void_tag, bool b) {
283   if (b)
284     co_return; // expected-note {{use of 'co_return'}}
285   else
286     return; // expected-error {{not allowed in coroutine}}
287 }
288 
289 void mixed_coreturn_return_first(void_tag, bool b) {
290   if (b)
291     return; // expected-error {{not allowed in coroutine}}
292   else
293     co_return; // expected-note {{use of 'co_return'}}
294 }
295 
296 void mixed_coreturn_invalid(bool b) {
297   if (b)
298     co_return; // expected-note {{use of 'co_return'}}
299     // expected-error@-1 {{no member named 'return_void' in 'promise'}}
300   else
301     return; // expected-error {{not allowed in coroutine}}
302 }
303 
304 template <class T>
305 void mixed_coreturn_template(void_tag, bool b, T v) {
306   if (b)
307     co_return v; // expected-note {{use of 'co_return'}}
308     // expected-error@-1 {{no member named 'return_value' in 'promise_void'}}
309   else
310     return; // expected-error {{not allowed in coroutine}}
311 }
312 template void mixed_coreturn_template(void_tag, bool, int); // expected-note {{requested here}}
313 
314 template <class T>
315 void mixed_coreturn_template2(bool b, T) {
316   if (b)
317     co_return v; // expected-note {{use of 'co_return'}}
318     // expected-error@-1 {{use of undeclared identifier 'v'}}
319   else
320     return; // expected-error {{not allowed in coroutine}}
321 }
322 
323 struct promise_handle;
324 
325 struct Handle : std::coroutine_handle<promise_handle> { // expected-note 4{{not viable}}
326     // expected-note@-1 4{{not viable}}
327     using promise_type = promise_handle;
328 };
329 
330 struct promise_handle {
331     Handle get_return_object() noexcept {
332       { return Handle(std::coroutine_handle<Handle::promise_type>::from_promise(*this)); }
333     }
334     suspend_never initial_suspend() const noexcept { return {}; }
335     suspend_never final_suspend() const noexcept { return {}; }
336     void return_void() const noexcept {}
337     void unhandled_exception() const noexcept {}
338 };
339 
340 Handle mixed_return_value() {
341   co_await a; // expected-note {{function is a coroutine due to use of 'co_await' here}}
342   return 0; // expected-error {{return statement not allowed in coroutine}}
343   // expected-error@-1 {{no viable conversion from returned value of type}}
344   // Check that we first show that return is not allowed in coroutine.
345   // The error about bad conversion is most likely spurious so we prefer to have it afterwards.
346   // CHECK-NOT: error: no viable conversion from returned value of type
347   // CHECK: error: return statement not allowed in coroutine
348   // CHECK: error: no viable conversion from returned value of type
349 }
350 
351 Handle mixed_return_value_return_first(bool b) {
352   if (b) {
353     return 0; // expected-error {{no viable conversion from returned value of type}}
354     // expected-error@-1 {{return statement not allowed in coroutine}}
355   }
356   co_await a; // expected-note {{function is a coroutine due to use of 'co_await' here}}
357   co_return 0; // expected-error {{no member named 'return_value' in 'promise_handle'}}
358 }
359 
360 Handle mixed_multiple_returns(bool b) {
361   if (b) {
362     return 0; // expected-error {{no viable conversion from returned value of type}}
363     // expected-error@-1 {{return statement not allowed in coroutine}}
364   }
365   co_await a; // expected-note {{function is a coroutine due to use of 'co_await' here}}
366   // The error 'return statement not allowed in coroutine' should appear only once.
367   return 0; // expected-error {{no viable conversion from returned value of type}}
368 }
369 
370 struct CtorDtor {
371   CtorDtor() {
372     co_yield 0; // expected-error {{'co_yield' cannot be used in a constructor}}
373   }
374   CtorDtor(awaitable a) {
375     // The spec doesn't say this is ill-formed, but it must be.
376     co_await a; // expected-error {{'co_await' cannot be used in a constructor}}
377   }
378   ~CtorDtor() {
379     co_return 0; // expected-error {{'co_return' cannot be used in a destructor}}
380   }
381   void operator=(CtorDtor&) {
382     co_yield 0; // OK.
383   }
384   void operator=(CtorDtor const &) {
385     co_yield 0; // OK.
386   }
387   void operator=(CtorDtor &&) {
388     co_await a; // OK.
389   }
390   void operator=(CtorDtor const &&) {
391     co_await a; // OK.
392   }
393   void operator=(int) {
394     co_await a; // OK. Not a special member
395   }
396 };
397 
398 namespace std { class type_info; }
399 
400 void unevaluated() {
401   decltype(co_await a); // expected-error {{'co_await' cannot be used in an unevaluated context}}
402 }
403 
404 void unevaluated2() {
405   sizeof(co_await a); // expected-error {{'co_await' cannot be used in an unevaluated context}}
406 }
407 
408 void unevaluated3() {
409   typeid(co_await a); // expected-error {{'co_await' cannot be used in an unevaluated context}}
410 }
411 
412 void unevaluated4() {
413   decltype(co_yield 1); // expected-error {{'co_yield' cannot be used in an unevaluated context}}
414 }
415 
416 void unevaluated5() {
417   sizeof(co_yield 2); // expected-error {{'co_yield' cannot be used in an unevaluated context}}
418 }
419 
420 void unevaluated6() {
421   typeid(co_yield 3); // expected-error {{'co_yield' cannot be used in an unevaluated context}}
422 }
423 
424 // [expr.await]p2: "An await-expression shall not appear in a default argument."
425 // FIXME: A better diagnostic would explicitly state that default arguments are
426 // not allowed. A user may not understand that this is "outside a function."
427 void default_argument(int arg = co_await 0) {} // expected-error {{'co_await' cannot be used outside a function}}
428 
429 void await_in_catch_coroutine() {
430   try {
431   } catch (...) { // FIXME: Emit a note diagnostic pointing out the try handler on this line.
432     []() -> void { co_await a; }(); // OK
433     co_await a; // expected-error {{'co_await' cannot be used in the handler of a try block}}
434   }
435 }
436 
437 void await_nested_in_catch_coroutine() {
438   try {
439   } catch (...) { // FIXME: Emit a note diagnostic pointing out the try handler on this line.
440     try {
441       co_await a; // expected-error {{'co_await' cannot be used in the handler of a try block}}
442       []() -> void { co_await a; }(); // OK
443     } catch (...) {
444       co_return 123;
445     }
446   }
447 }
448 
449 void await_in_lambda_in_catch_coroutine() {
450   try {
451   } catch (...) {
452     []() -> void { co_await a; }(); // OK
453   }
454 }
455 
456 void yield_in_catch_coroutine() {
457   try {
458   } catch (...) {
459     co_yield 1; // expected-error {{'co_yield' cannot be used in the handler of a try block}}
460   }
461 }
462 
463 void return_in_catch_coroutine() {
464   try {
465   } catch (...) {
466     co_return 123; // OK
467   }
468 }
469 
470 constexpr auto constexpr_deduced_return_coroutine() {
471   co_yield 0; // expected-error {{'co_yield' cannot be used in a constexpr function}}
472   // expected-error@-1 {{'co_yield' cannot be used in a function with a deduced return type}}
473 }
474 
475 void varargs_coroutine(const char *, ...) {
476   co_await a; // expected-error {{'co_await' cannot be used in a varargs function}}
477 }
478 
479 auto deduced_return_coroutine() {
480   co_await a; // expected-error {{'co_await' cannot be used in a function with a deduced return type}}
481 }
482 
483 struct outer {};
484 struct await_arg_1 {};
485 struct await_arg_2 {};
486 
487 namespace adl_ns {
488 struct coawait_arg_type {};
489 awaitable operator co_await(coawait_arg_type) noexcept;
490 }
491 
492 namespace dependent_operator_co_await_lookup {
493   template<typename T> void await_template(T t) {
494     // no unqualified lookup results
495     co_await t; // expected-error {{no member named 'await_ready' in 'dependent_operator_co_await_lookup::not_awaitable'}}
496     // expected-error@-1 {{call to function 'operator co_await' that is neither visible in the template definition nor found by argument-dependent lookup}}
497   };
498   template void await_template(awaitable);
499 
500   struct indirectly_awaitable { indirectly_awaitable(outer); };
501   awaitable operator co_await(indirectly_awaitable); // expected-note {{should be declared prior to}}
502   template void await_template(indirectly_awaitable);
503 
504   struct not_awaitable {};
505   template void await_template(not_awaitable); // expected-note {{instantiation}}
506 
507   template<typename T> void await_template_2(T t) {
508     // one unqualified lookup result
509     co_await t;
510   };
511   template void await_template(outer); // expected-note {{instantiation}}
512   template void await_template_2(outer);
513 
514   struct transform_awaitable {};
515   struct transformed {};
516 
517   struct transform_promise {
518     typedef transform_awaitable await_arg;
519     coro<transform_promise> get_return_object();
520     transformed initial_suspend();
521     ::adl_ns::coawait_arg_type final_suspend() noexcept;
522     transformed await_transform(transform_awaitable);
523     void unhandled_exception();
524     void return_void();
525   };
526   template <class AwaitArg>
527   struct basic_promise {
528     typedef AwaitArg await_arg;
529     coro<basic_promise> get_return_object();
530     awaitable initial_suspend();
531     awaitable final_suspend() noexcept;
532     void unhandled_exception();
533     void return_void();
534   };
535 
536   awaitable operator co_await(await_arg_1);
537 
538   template <typename T, typename U>
539   coro<T> await_template_3(U t) {
540     co_await t;
541   }
542 
543   template coro<basic_promise<await_arg_1>> await_template_3<basic_promise<await_arg_1>>(await_arg_1);
544 
545   template <class T, int I = 0>
546   struct dependent_member {
547     coro<T> mem_fn() const {
548       co_await typename T::await_arg{}; // expected-error {{call to function 'operator co_await'}}}
549     }
550     template <class U>
551     coro<T> dep_mem_fn(U t) {
552       co_await t;
553     }
554   };
555 
556   template <>
557   struct dependent_member<long> {
558     // FIXME this diagnostic is terrible
559     coro<transform_promise> mem_fn() const { // expected-error {{no member named 'await_ready' in 'dependent_operator_co_await_lookup::transformed'}}
560       // expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
561       // expected-note@+1 {{function is a coroutine due to use of 'co_await' here}}
562       co_await transform_awaitable{};
563       // expected-error@-1 {{no member named 'await_ready'}}
564     }
565     template <class R, class U>
566     coro<R> dep_mem_fn(U u) { co_await u; }
567   };
568 
569   awaitable operator co_await(await_arg_2); // expected-note {{'operator co_await' should be declared prior to the call site}}
570 
571   template struct dependent_member<basic_promise<await_arg_1>, 0>;
572   template struct dependent_member<basic_promise<await_arg_2>, 0>; // expected-note {{in instantiation}}
573 
574   template <>
575   coro<transform_promise>
576       // FIXME this diagnostic is terrible
577       dependent_member<long>::dep_mem_fn<transform_promise>(int) { // expected-error {{no member named 'await_ready' in 'dependent_operator_co_await_lookup::transformed'}}
578     //expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
579     //expected-note@+1 {{function is a coroutine due to use of 'co_await' here}}
580     co_await transform_awaitable{};
581     // expected-error@-1 {{no member named 'await_ready'}}
582   }
583 
584   void operator co_await(transform_awaitable) = delete;
585   awaitable operator co_await(transformed);
586 
587   template coro<transform_promise>
588       dependent_member<long>::dep_mem_fn<transform_promise>(transform_awaitable);
589 
590   template <>
591   coro<transform_promise> dependent_member<long>::dep_mem_fn<transform_promise>(long) {
592     co_await transform_awaitable{};
593   }
594 
595   template <>
596   struct dependent_member<int> {
597     coro<transform_promise> mem_fn() const {
598       co_await transform_awaitable{};
599     }
600   };
601 
602   template coro<transform_promise> await_template_3<transform_promise>(transform_awaitable);
603   template struct dependent_member<transform_promise>;
604   template coro<transform_promise> dependent_member<transform_promise>::dep_mem_fn(transform_awaitable);
605 }
606 
607 struct yield_fn_tag {};
608 template <>
609 struct std::coroutine_traits<void, yield_fn_tag> {
610   struct promise_type {
611     // FIXME: add an await_transform overload for functions
612     awaitable yield_value(int());
613     void return_value(int());
614 
615     suspend_never initial_suspend();
616     suspend_never final_suspend() noexcept;
617     void get_return_object();
618     void unhandled_exception();
619   };
620 };
621 
622 namespace placeholder {
623   awaitable f(), f(int); // expected-note 4{{possible target}}
624   int g(), g(int); // expected-note 2{{candidate}}
625   void x() {
626     co_await f; // expected-error {{reference to overloaded function}}
627   }
628   void y() {
629     co_yield g; // expected-error {{no matching member function for call to 'yield_value'}}
630   }
631   void z() {
632     co_await a;
633     co_return g; // expected-error {{address of overloaded function 'g' does not match required type 'int'}}
634   }
635 
636   void x(yield_fn_tag) {
637     co_await f; // expected-error {{reference to overloaded function}}
638   }
639   void y(yield_fn_tag) {
640     co_yield g;
641   }
642   void z(yield_fn_tag) {
643     co_await a;
644     co_return g;
645   }
646 }
647 
648 struct bad_promise_1 {
649   suspend_always initial_suspend();
650   suspend_always final_suspend() noexcept;
651   void unhandled_exception();
652   void return_void();
653 };
654 coro<bad_promise_1> missing_get_return_object() { // expected-error {{no member named 'get_return_object' in 'bad_promise_1'}}
655   co_await a;
656 }
657 
658 struct bad_promise_2 {
659   coro<bad_promise_2> get_return_object();
660   suspend_always final_suspend() noexcept;
661   void unhandled_exception();
662   void return_void();
663 };
664 // FIXME: This shouldn't happen twice
665 coro<bad_promise_2> missing_initial_suspend() { // expected-error {{no member named 'initial_suspend' in 'bad_promise_2'}}
666   co_await a;
667 }
668 
669 struct bad_promise_3 {
670   coro<bad_promise_3> get_return_object();
671   suspend_always initial_suspend();
672   void unhandled_exception();
673   void return_void();
674 };
675 coro<bad_promise_3> missing_final_suspend() noexcept { // expected-error {{no member named 'final_suspend' in 'bad_promise_3'}}
676   co_await a;
677 }
678 
679 struct bad_promise_4 {
680   coro<bad_promise_4> get_return_object();
681   not_awaitable initial_suspend();
682   suspend_always final_suspend() noexcept;
683   void return_void();
684 };
685 // FIXME: This diagnostic is terrible.
686 coro<bad_promise_4> bad_initial_suspend() { // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
687   // expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
688   co_await a; // expected-note {{function is a coroutine due to use of 'co_await' here}}
689 }
690 
691 struct bad_promise_5 {
692   coro<bad_promise_5> get_return_object();
693   suspend_always initial_suspend();
694   not_awaitable final_suspend() noexcept;
695   void return_void();
696 };
697 // FIXME: This diagnostic is terrible.
698 coro<bad_promise_5> bad_final_suspend() { // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
699   // expected-note@-1 {{call to 'final_suspend' implicitly required by the final suspend point}}
700   co_await a; // expected-note {{function is a coroutine due to use of 'co_await' here}}
701 }
702 
703 struct bad_promise_6 {
704   coro<bad_promise_6> get_return_object();
705   suspend_always initial_suspend();
706   suspend_always final_suspend() noexcept;
707   void unhandled_exception();
708   void return_void();           // expected-note 2 {{member 'return_void' first declared here}}
709   void return_value(int) const; // expected-note 2 {{member 'return_value' first declared here}}
710   void return_value(int);
711 };
712 coro<bad_promise_6> bad_implicit_return() { // expected-error {{'bad_promise_6' declares both 'return_value' and 'return_void'}}
713   co_await a;
714 }
715 
716 template <class T>
717 coro<T> bad_implicit_return_dependent(T) { // expected-error {{'bad_promise_6' declares both 'return_value' and 'return_void'}}
718   co_await a;
719 }
720 template coro<bad_promise_6> bad_implicit_return_dependent(bad_promise_6); // expected-note {{in instantiation}}
721 
722 struct bad_promise_7 { // expected-note 2 {{defined here}}
723   coro<bad_promise_7> get_return_object();
724   suspend_always initial_suspend();
725   suspend_always final_suspend() noexcept;
726   void return_void();
727 };
728 coro<bad_promise_7> no_unhandled_exception() { // expected-error {{'bad_promise_7' is required to declare the member 'unhandled_exception()'}}
729   co_await a;
730 }
731 
732 template <class T>
733 coro<T> no_unhandled_exception_dependent(T) { // expected-error {{'bad_promise_7' is required to declare the member 'unhandled_exception()'}}
734   co_await a;
735 }
736 template coro<bad_promise_7> no_unhandled_exception_dependent(bad_promise_7); // expected-note {{in instantiation}}
737 
738 struct bad_promise_base {
739 private:
740   void return_void(); // expected-note 2 {{declared private here}}
741 };
742 struct bad_promise_8 : bad_promise_base {
743   coro<bad_promise_8> get_return_object();
744   suspend_always initial_suspend();
745   suspend_always final_suspend() noexcept;
746   void unhandled_exception() __attribute__((unavailable)); // expected-note 2 {{marked unavailable here}}
747   void unhandled_exception() const;
748   void unhandled_exception(void *) const;
749 };
750 coro<bad_promise_8> calls_unhandled_exception() {
751   // expected-error@-1 {{'unhandled_exception' is unavailable}}
752   // expected-error@-2 {{'return_void' is a private member}}
753   co_await a;
754 }
755 
756 template <class T>
757 coro<T> calls_unhandled_exception_dependent(T) {
758   // expected-error@-1 {{'unhandled_exception' is unavailable}}
759   // expected-error@-2 {{'return_void' is a private member}}
760   co_await a;
761 }
762 template coro<bad_promise_8> calls_unhandled_exception_dependent(bad_promise_8); // expected-note {{in instantiation}}
763 
764 struct bad_promise_9 {
765   coro<bad_promise_9> get_return_object();
766   suspend_always initial_suspend();
767   suspend_always final_suspend() noexcept;
768   void await_transform(void *);
769   awaitable await_transform(int) __attribute__((unavailable)); // expected-note {{explicitly marked unavailable}}
770   void return_void();
771   void unhandled_exception();
772 };
773 coro<bad_promise_9> calls_await_transform() {
774   co_await 42; // expected-error {{'await_transform' is unavailable}}
775 }
776 
777 struct bad_promise_10 {
778   coro<bad_promise_10> get_return_object();
779   suspend_always initial_suspend();
780   suspend_always final_suspend() noexcept;
781   int await_transform;
782   void return_void();
783   void unhandled_exception();
784 };
785 coro<bad_promise_10> bad_coawait() {
786   // FIXME this diagnostic is terrible
787   co_await 42; // expected-error {{called object type 'int' is not a function or function pointer}}
788   // expected-note@-1 {{call to 'await_transform' implicitly required by 'co_await' here}}
789 }
790 
791 struct call_operator {
792   template <class... Args>
793   awaitable operator()(Args...) const { return a; }
794 };
795 void ret_void();
796 struct good_promise_1 {
797   coro<good_promise_1> get_return_object();
798   suspend_always initial_suspend();
799   suspend_always final_suspend() noexcept;
800   void unhandled_exception();
801   static const call_operator await_transform;
802   using Fn = void (*)();
803   Fn return_void = ret_void;
804 };
805 const call_operator good_promise_1::await_transform;
806 coro<good_promise_1> ok_static_coawait() {
807   // FIXME this diagnostic is terrible
808   co_await 42;
809 }
810 
811 template<typename T> void ok_generic_lambda_coawait_PR41909() {
812   [](auto& arg) -> coro<good_promise_1> { // expected-warning {{expression result unused}}
813     co_await 12;
814   };
815   [](auto &arg) -> coro<good_promise_1> {
816     co_await 24;
817   }("argument");
818   [](auto &arg) ->coro<good_promise_1> { // expected-warning {{expression result unused}}
819     []() -> coro<good_promise_1> {
820       co_await 36;
821     };
822     co_await 48;
823   };
824 }
825 template void ok_generic_lambda_coawait_PR41909<int>(); // expected-note {{in instantiation of function template specialization 'ok_generic_lambda_coawait_PR41909<int>' requested here}}
826 
827 template <> struct std::coroutine_traits<int, int, const char **> { using promise_type = promise; };
828 
829 int main(int, const char**) {
830   co_await a; // expected-error {{'co_await' cannot be used in the 'main' function}}
831 }
832 
833 struct good_promise_2 {
834   float get_return_object();
835   suspend_always initial_suspend();
836   suspend_always final_suspend() noexcept;
837   void return_void();
838   void unhandled_exception();
839 };
840 template <> struct std::coroutine_handle<good_promise_2> {};
841 
842 template <> struct std::coroutine_traits<float> { using promise_type = good_promise_2; };
843 
844 float badly_specialized_coro_handle() { // expected-error {{std::coroutine_handle must have a member named 'from_address'}}
845   //expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
846   co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
847 }
848 
849 namespace std {
850   struct nothrow_t {};
851   constexpr nothrow_t nothrow = {};
852 }
853 
854 using SizeT = decltype(sizeof(int));
855 
856 void* operator new(SizeT __sz, const std::nothrow_t&) noexcept;
857 void  operator delete(void* __p, const std::nothrow_t&) noexcept;
858 
859 
860 
861 struct promise_on_alloc_failure_tag {};
862 
863 template <>
864 struct std::coroutine_traits<int, promise_on_alloc_failure_tag> {
865   struct promise_type {
866     int get_return_object() {}
867     suspend_always initial_suspend() { return {}; }
868     suspend_always final_suspend() noexcept { return {}; }
869     void return_void() {}
870     int get_return_object_on_allocation_failure(); // expected-error{{'promise_type': 'get_return_object_on_allocation_failure()' must be a static member function}}
871     void unhandled_exception();
872   };
873 };
874 
875 extern "C" int f(promise_on_alloc_failure_tag) {
876   co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
877 }
878 
879 struct bad_promise_11 {
880   coro<bad_promise_11> get_return_object();
881   suspend_always initial_suspend();
882   suspend_always final_suspend() noexcept;
883   void unhandled_exception();
884   void return_void();
885 
886 private:
887   static coro<bad_promise_11> get_return_object_on_allocation_failure(); // expected-note 2 {{declared private here}}
888 };
889 coro<bad_promise_11> private_alloc_failure_handler() {
890   // expected-error@-1 {{'get_return_object_on_allocation_failure' is a private member of 'bad_promise_11'}}
891   co_return; // FIXME: Add a "declared coroutine here" note.
892 }
893 
894 template <class T>
895 coro<T> dependent_private_alloc_failure_handler(T) {
896   // expected-error@-1 {{'get_return_object_on_allocation_failure' is a private member of 'bad_promise_11'}}
897   co_return; // FIXME: Add a "declared coroutine here" note.
898 }
899 template coro<bad_promise_11> dependent_private_alloc_failure_handler(bad_promise_11);
900 // expected-note@-1 {{requested here}}
901 
902 struct bad_promise_12 {
903   coro<bad_promise_12> get_return_object();
904   suspend_always initial_suspend();
905   suspend_always final_suspend() noexcept;
906   void unhandled_exception();
907   void return_void();
908   static coro<bad_promise_12> get_return_object_on_allocation_failure();
909 
910   static void* operator new(SizeT);
911   // expected-error@-1 2 {{'operator new' is required to have a non-throwing noexcept specification when the promise type declares 'get_return_object_on_allocation_failure()'}}
912 };
913 coro<bad_promise_12> throwing_in_class_new() { // expected-note {{call to 'operator new' implicitly required by coroutine function here}}
914   co_return;
915 }
916 
917 template <class T>
918 coro<T> dependent_throwing_in_class_new(T) { // expected-note {{call to 'operator new' implicitly required by coroutine function here}}
919    co_return;
920 }
921 template coro<bad_promise_12> dependent_throwing_in_class_new(bad_promise_12); // expected-note {{requested here}}
922 
923 
924 struct good_promise_13 {
925   coro<good_promise_13> get_return_object();
926   suspend_always initial_suspend();
927   suspend_always final_suspend() noexcept;
928   void unhandled_exception();
929   void return_void();
930   static coro<good_promise_13> get_return_object_on_allocation_failure();
931 };
932 coro<good_promise_13> uses_nothrow_new() {
933   co_return;
934 }
935 
936 template <class T>
937 coro<T> dependent_uses_nothrow_new(T) {
938    co_return;
939 }
940 template coro<good_promise_13> dependent_uses_nothrow_new(good_promise_13);
941 
942 struct good_promise_custom_new_operator {
943   coro<good_promise_custom_new_operator> get_return_object();
944   suspend_always initial_suspend();
945   suspend_always final_suspend() noexcept;
946   void return_void();
947   void unhandled_exception();
948   void *operator new(SizeT, double, float, int);
949 };
950 
951 coro<good_promise_custom_new_operator>
952 good_coroutine_calls_custom_new_operator(double, float, int) {
953   co_return;
954 }
955 
956 struct coroutine_nonstatic_member_struct;
957 
958 struct good_promise_nonstatic_member_custom_new_operator {
959   coro<good_promise_nonstatic_member_custom_new_operator> get_return_object();
960   suspend_always initial_suspend();
961   suspend_always final_suspend() noexcept;
962   void return_void();
963   void unhandled_exception();
964   void *operator new(SizeT, coroutine_nonstatic_member_struct &, double);
965 };
966 
967 struct good_promise_noexcept_custom_new_operator {
968   static coro<good_promise_noexcept_custom_new_operator> get_return_object_on_allocation_failure();
969   coro<good_promise_noexcept_custom_new_operator> get_return_object();
970   suspend_always initial_suspend();
971   suspend_always final_suspend() noexcept;
972   void return_void();
973   void unhandled_exception();
974   void *operator new(SizeT, double, float, int) noexcept;
975 };
976 
977 coro<good_promise_noexcept_custom_new_operator>
978 good_coroutine_calls_noexcept_custom_new_operator(double, float, int) {
979   co_return;
980 }
981 
982 struct mismatch_gro_type_tag1 {};
983 template <>
984 struct std::coroutine_traits<int, mismatch_gro_type_tag1> {
985   struct promise_type {
986     void get_return_object() {} //expected-note {{member 'get_return_object' declared here}}
987     suspend_always initial_suspend() { return {}; }
988     suspend_always final_suspend() noexcept { return {}; }
989     void return_void() {}
990     void unhandled_exception();
991   };
992 };
993 
994 extern "C" int f(mismatch_gro_type_tag1) {
995   // expected-error@-1 {{cannot initialize return object of type 'int' with an rvalue of type 'void'}}
996   co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
997 }
998 
999 struct mismatch_gro_type_tag2 {};
1000 template <>
1001 struct std::coroutine_traits<int, mismatch_gro_type_tag2> {
1002   struct promise_type {
1003     void *get_return_object() {} //expected-note {{member 'get_return_object' declared here}}
1004     suspend_always initial_suspend() { return {}; }
1005     suspend_always final_suspend() noexcept { return {}; }
1006     void return_void() {}
1007     void unhandled_exception();
1008   };
1009 };
1010 
1011 extern "C" int f(mismatch_gro_type_tag2) {
1012   // cxx23-error@-1 {{cannot initialize return object of type 'int' with an rvalue of type 'void *'}}
1013   // cxx14_20-error@-2 {{cannot initialize return object of type 'int' with an lvalue of type 'void *'}}
1014   co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
1015 }
1016 
1017 struct mismatch_gro_type_tag3 {};
1018 template <>
1019 struct std::coroutine_traits<int, mismatch_gro_type_tag3> {
1020   struct promise_type {
1021     int get_return_object() {}
1022     static void get_return_object_on_allocation_failure() {} //expected-note {{member 'get_return_object_on_allocation_failure' declared here}}
1023     suspend_always initial_suspend() { return {}; }
1024     suspend_always final_suspend() noexcept { return {}; }
1025     void return_void() {}
1026     void unhandled_exception();
1027   };
1028 };
1029 
1030 extern "C" int f(mismatch_gro_type_tag3) {
1031   // expected-error@-1 {{cannot initialize return object of type 'int' with an rvalue of type 'void'}}
1032   co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
1033 }
1034 
1035 
1036 struct mismatch_gro_type_tag4 {};
1037 template <>
1038 struct std::coroutine_traits<int, mismatch_gro_type_tag4> {
1039   struct promise_type {
1040     int get_return_object() {}
1041     static char *get_return_object_on_allocation_failure() {} //expected-note {{member 'get_return_object_on_allocation_failure' declared}}
1042     suspend_always initial_suspend() { return {}; }
1043     suspend_always final_suspend() noexcept { return {}; }
1044     void return_void() {}
1045     void unhandled_exception();
1046   };
1047 };
1048 
1049 extern "C" int f(mismatch_gro_type_tag4) {
1050   // expected-error@-1 {{cannot initialize return object of type 'int' with an rvalue of type 'char *'}}
1051   co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
1052 }
1053 
1054 struct promise_no_return_func {
1055   coro<promise_no_return_func> get_return_object();
1056   suspend_always initial_suspend();
1057   suspend_always final_suspend() noexcept;
1058   void unhandled_exception();
1059 };
1060 // [dcl.fct.def.coroutine]/p6
1061 // If searches for the names return_­void and return_­value in the scope of
1062 // the promise type each find any declarations, the program is ill-formed.
1063 // [Note 1: If return_­void is found, flowing off the end of a coroutine is
1064 // equivalent to a co_­return with no operand. Otherwise, flowing off the end
1065 // of a coroutine results in undefined behavior ([stmt.return.coroutine]). —
1066 // end note]
1067 //
1068 // So it isn't ill-formed if the promise doesn't define return_value and return_void.
1069 // It is just a potential UB.
1070 coro<promise_no_return_func> no_return_value_or_return_void() {
1071   co_await a;
1072 }
1073 
1074 // The following two tests that it would emit correct diagnostic message
1075 // if we co_return in `promise_no_return_func`.
1076 coro<promise_no_return_func> no_return_value_or_return_void_2() {
1077   co_return; // expected-error {{no member named 'return_void'}}
1078 }
1079 
1080 coro<promise_no_return_func> no_return_value_or_return_void_3() {
1081   co_return 43; // expected-error {{no member named 'return_value'}}
1082 }
1083 
1084 struct bad_await_suspend_return {
1085   bool await_ready();
1086   // expected-error@+1 {{return type of 'await_suspend' is required to be 'void' or 'bool' (have 'char')}}
1087   char await_suspend(std::coroutine_handle<>);
1088   void await_resume();
1089 };
1090 struct bad_await_ready_return {
1091   // expected-note@+1 {{return type of 'await_ready' is required to be contextually convertible to 'bool'}}
1092   void await_ready();
1093   bool await_suspend(std::coroutine_handle<>);
1094   void await_resume();
1095 };
1096 struct await_ready_explicit_bool {
1097   struct BoolT {
1098     explicit operator bool() const;
1099   };
1100   BoolT await_ready();
1101   void await_suspend(std::coroutine_handle<>);
1102   void await_resume();
1103 };
1104 template <class SuspendTy>
1105 struct await_suspend_type_test {
1106   bool await_ready();
1107   // expected-error@+2 {{return type of 'await_suspend' is required to be 'void' or 'bool' (have 'bool &')}}
1108   // expected-error@+1 {{return type of 'await_suspend' is required to be 'void' or 'bool' (have 'bool &&')}}
1109   SuspendTy await_suspend(std::coroutine_handle<>);
1110   // cxx20_23-warning@-1 {{volatile-qualified return type 'const volatile bool' is deprecated}}
1111   void await_resume();
1112 };
1113 void test_bad_suspend() {
1114   {
1115     // FIXME: The actual error emitted here is terrible, and no number of notes can save it.
1116     bad_await_ready_return a;
1117     // expected-error@+1 {{value of type 'void' is not contextually convertible to 'bool'}}
1118     co_await a; // expected-note {{call to 'await_ready' implicitly required by coroutine function here}}
1119   }
1120   {
1121     bad_await_suspend_return b;
1122     co_await b; // expected-note {{call to 'await_suspend' implicitly required by coroutine function here}}
1123   }
1124   {
1125     await_ready_explicit_bool c;
1126     co_await c; // OK
1127   }
1128   {
1129     await_suspend_type_test<bool &&> a;
1130     await_suspend_type_test<bool &> b;
1131     await_suspend_type_test<const void> c;
1132     await_suspend_type_test<const volatile bool> d; // cxx20_23-note {{in instantiation of template class}}
1133     co_await a; // expected-note {{call to 'await_suspend' implicitly required by coroutine function here}}
1134     co_await b; // expected-note {{call to 'await_suspend' implicitly required by coroutine function here}}
1135     co_await c; // OK
1136     co_await d; // OK
1137   }
1138 }
1139 
1140 template <int ID = 0>
1141 struct NoCopy {
1142   NoCopy(NoCopy const&) = delete; // expected-note 2 {{deleted here}}
1143 };
1144 template <class T, class U>
1145 void test_dependent_param(T t, U) {
1146   // expected-error@-1 {{call to deleted constructor of 'NoCopy<>'}}
1147   // expected-error@-2 {{call to deleted constructor of 'NoCopy<1>'}}
1148   ((void)t);
1149   co_return 42;
1150 }
1151 template void test_dependent_param(NoCopy<0>, NoCopy<1>); // expected-note {{requested here}}
1152 
1153 namespace CoroHandleMemberFunctionTest {
1154 struct CoroMemberTag {};
1155 struct BadCoroMemberTag {};
1156 
1157 template <class T, class U>
1158 constexpr bool IsSameV = false;
1159 template <class T>
1160 constexpr bool IsSameV<T, T> = true;
1161 
1162 template <class T>
1163 struct TypeTest {
1164   template <class U>
1165   static constexpr bool IsSame = IsSameV<T, U>;
1166 
1167   template <class... Args>
1168   static constexpr bool MatchesArgs = IsSameV<T,
1169                                               std::coroutine_traits<CoroMemberTag, Args...>>;
1170 };
1171 
1172 template <class T>
1173 struct AwaitReturnsType {
1174   bool await_ready() const;
1175   void await_suspend(...) const;
1176   T await_resume() const;
1177 };
1178 
1179 template <class... CoroTraitsArgs>
1180 struct CoroMemberPromise {
1181   using TraitsT = std::coroutine_traits<CoroTraitsArgs...>;
1182   using TypeTestT = TypeTest<TraitsT>;
1183   using AwaitTestT = AwaitReturnsType<TypeTestT>;
1184 
1185   CoroMemberTag get_return_object();
1186   suspend_always initial_suspend();
1187   suspend_always final_suspend() noexcept;
1188 
1189   AwaitTestT yield_value(int);
1190 
1191   void return_void();
1192   void unhandled_exception();
1193 };
1194 
1195 } // namespace CoroHandleMemberFunctionTest
1196 
1197 template <class... Args>
1198 struct ::std::coroutine_traits<CoroHandleMemberFunctionTest::CoroMemberTag, Args...> {
1199   using promise_type = CoroHandleMemberFunctionTest::CoroMemberPromise<CoroHandleMemberFunctionTest::CoroMemberTag, Args...>;
1200 };
1201 
1202 namespace CoroHandleMemberFunctionTest {
1203 struct TestType {
1204 
1205   CoroMemberTag test_qual() {
1206     auto TC = co_yield 0;
1207     static_assert(TC.MatchesArgs<TestType &>, "");
1208     static_assert(!TC.MatchesArgs<TestType>, "");
1209     static_assert(!TC.MatchesArgs<TestType *>, "");
1210   }
1211 
1212   CoroMemberTag test_asserts(int *) const {
1213     auto TC = co_yield 0;
1214     static_assert(TC.MatchesArgs<const TestType &>, ""); // expected-error {{static assertion failed}}
1215     static_assert(TC.MatchesArgs<const TestType &>, ""); // expected-error {{static assertion failed}}
1216     static_assert(TC.MatchesArgs<const TestType &, int *>, "");
1217   }
1218 
1219   CoroMemberTag test_qual(int *, const float &&, volatile void *volatile) const {
1220     // cxx20_23-warning@-1 {{volatile-qualified parameter type}}
1221     auto TC = co_yield 0;
1222     static_assert(TC.MatchesArgs<const TestType &, int *, const float &&, volatile void *volatile>, "");
1223   }
1224 
1225   CoroMemberTag test_qual() const volatile {
1226     auto TC = co_yield 0;
1227     static_assert(TC.MatchesArgs<const volatile TestType &>, "");
1228   }
1229 
1230   CoroMemberTag test_ref_qual() & {
1231     auto TC = co_yield 0;
1232     static_assert(TC.MatchesArgs<TestType &>, "");
1233   }
1234   CoroMemberTag test_ref_qual() const & {
1235     auto TC = co_yield 0;
1236     static_assert(TC.MatchesArgs<TestType const &>, "");
1237   }
1238   CoroMemberTag test_ref_qual() && {
1239     auto TC = co_yield 0;
1240     static_assert(TC.MatchesArgs<TestType &&>, "");
1241   }
1242   CoroMemberTag test_ref_qual(const char *&) const volatile && {
1243     auto TC = co_yield 0;
1244     static_assert(TC.MatchesArgs<TestType const volatile &&, const char *&>, "");
1245   }
1246 
1247   CoroMemberTag test_args(int) {
1248     auto TC = co_yield 0;
1249     static_assert(TC.MatchesArgs<TestType &, int>, "");
1250   }
1251   CoroMemberTag test_args(int, long &, void *) const {
1252     auto TC = co_yield 0;
1253     static_assert(TC.MatchesArgs<TestType const &, int, long &, void *>, "");
1254   }
1255 
1256   template <class... Args>
1257   CoroMemberTag test_member_template(Args...) const && {
1258     auto TC = co_yield 0;
1259     static_assert(TC.template MatchesArgs<TestType const &&, Args...>, "");
1260   }
1261 
1262   static CoroMemberTag test_static() {
1263     auto TC = co_yield 0;
1264     static_assert(TC.MatchesArgs<>, "");
1265     static_assert(!TC.MatchesArgs<TestType>, "");
1266     static_assert(!TC.MatchesArgs<TestType &>, "");
1267     static_assert(!TC.MatchesArgs<TestType *>, "");
1268   }
1269 
1270   static CoroMemberTag test_static(volatile void *const, char &&) {
1271     auto TC = co_yield 0;
1272     static_assert(TC.MatchesArgs<volatile void *const, char &&>, "");
1273   }
1274 
1275   template <class Dummy>
1276   static CoroMemberTag test_static_template(const char *volatile &, unsigned) {
1277     auto TC = co_yield 0;
1278     using TCT = decltype(TC);
1279     static_assert(TCT::MatchesArgs<const char *volatile &, unsigned>, "");
1280     static_assert(!TCT::MatchesArgs<TestType &, const char *volatile &, unsigned>, "");
1281   }
1282 
1283   BadCoroMemberTag test_diagnostics() {
1284     // expected-error@-1 {{this function cannot be a coroutine: 'std::coroutine_traits<CoroHandleMemberFunctionTest::BadCoroMemberTag, CoroHandleMemberFunctionTest::TestType &>' has no member named 'promise_type'}}
1285     co_return;
1286   }
1287   BadCoroMemberTag test_diagnostics(int) const && {
1288     // expected-error@-1 {{this function cannot be a coroutine: 'std::coroutine_traits<CoroHandleMemberFunctionTest::BadCoroMemberTag, const CoroHandleMemberFunctionTest::TestType &&, int>' has no member named 'promise_type'}}
1289     co_return;
1290   }
1291 
1292   static BadCoroMemberTag test_static_diagnostics(long *) {
1293     // expected-error@-1 {{this function cannot be a coroutine: 'std::coroutine_traits<CoroHandleMemberFunctionTest::BadCoroMemberTag, long *>' has no member named 'promise_type'}}
1294     co_return;
1295   }
1296 };
1297 
1298 template CoroMemberTag TestType::test_member_template(long, const char *) const &&;
1299 template CoroMemberTag TestType::test_static_template<void>(const char *volatile &, unsigned);
1300 
1301 template <class... Args>
1302 struct DepTestType {
1303 
1304   CoroMemberTag test_asserts(int *) const {
1305     auto TC = co_yield 0;
1306     static_assert(TC.template MatchesArgs<const DepTestType &>, ""); // expected-error {{static assertion failed}}
1307     static_assert(TC.template MatchesArgs<>, ""); // expected-error {{static assertion failed}}
1308     static_assert(TC.template MatchesArgs<const DepTestType &, int *>, "");
1309   }
1310 
1311   CoroMemberTag test_qual() {
1312     auto TC = co_yield 0;
1313     static_assert(TC.template MatchesArgs<DepTestType &>, "");
1314     static_assert(!TC.template MatchesArgs<DepTestType>, "");
1315     static_assert(!TC.template MatchesArgs<DepTestType *>, "");
1316   }
1317 
1318   CoroMemberTag test_qual(int *, const float &&, volatile void *volatile) const {
1319     // cxx20_23-warning@-1 {{volatile-qualified parameter type}}
1320     auto TC = co_yield 0;
1321     static_assert(TC.template MatchesArgs<const DepTestType &, int *, const float &&, volatile void *volatile>, "");
1322   }
1323 
1324   CoroMemberTag test_qual() const volatile {
1325     auto TC = co_yield 0;
1326     static_assert(TC.template MatchesArgs<const volatile DepTestType &>, "");
1327   }
1328 
1329   CoroMemberTag test_ref_qual() & {
1330     auto TC = co_yield 0;
1331     static_assert(TC.template MatchesArgs<DepTestType &>, "");
1332   }
1333   CoroMemberTag test_ref_qual() const & {
1334     auto TC = co_yield 0;
1335     static_assert(TC.template MatchesArgs<DepTestType const &>, "");
1336   }
1337   CoroMemberTag test_ref_qual() && {
1338     auto TC = co_yield 0;
1339     static_assert(TC.template MatchesArgs<DepTestType &&>, "");
1340   }
1341   CoroMemberTag test_ref_qual(const char *&) const volatile && {
1342     auto TC = co_yield 0;
1343     static_assert(TC.template MatchesArgs<DepTestType const volatile &&, const char *&>, "");
1344   }
1345 
1346   CoroMemberTag test_args(int) {
1347     auto TC = co_yield 0;
1348     static_assert(TC.template MatchesArgs<DepTestType &, int>, "");
1349   }
1350   CoroMemberTag test_args(int, long &, void *) const {
1351     auto TC = co_yield 0;
1352     static_assert(TC.template MatchesArgs<DepTestType const &, int, long &, void *>, "");
1353   }
1354 
1355   template <class... UArgs>
1356   CoroMemberTag test_member_template(UArgs...) const && {
1357     auto TC = co_yield 0;
1358     static_assert(TC.template MatchesArgs<DepTestType const &&, UArgs...>, "");
1359   }
1360 
1361   static CoroMemberTag test_static() {
1362     auto TC = co_yield 0;
1363     using TCT = decltype(TC);
1364     static_assert(TCT::MatchesArgs<>, "");
1365     static_assert(!TCT::MatchesArgs<DepTestType>, "");
1366     static_assert(!TCT::MatchesArgs<DepTestType &>, "");
1367     static_assert(!TCT::MatchesArgs<DepTestType *>, "");
1368 
1369     // Ensure diagnostics are actually being generated here
1370     static_assert(TCT::MatchesArgs<int>, ""); // expected-error {{static assertion failed}}
1371   }
1372 
1373   static CoroMemberTag test_static(volatile void *const, char &&) {
1374     auto TC = co_yield 0;
1375     using TCT = decltype(TC);
1376     static_assert(TCT::MatchesArgs<volatile void *const, char &&>, "");
1377   }
1378 
1379   template <class Dummy>
1380   static CoroMemberTag test_static_template(const char *volatile &, unsigned) {
1381     auto TC = co_yield 0;
1382     using TCT = decltype(TC);
1383     static_assert(TCT::MatchesArgs<const char *volatile &, unsigned>, "");
1384     static_assert(!TCT::MatchesArgs<DepTestType &, const char *volatile &, unsigned>, "");
1385   }
1386 };
1387 
1388 template struct DepTestType<int>; // expected-note 2{{requested here}}
1389 template CoroMemberTag DepTestType<int>::test_member_template(long, const char *) const &&;
1390 
1391 template CoroMemberTag DepTestType<int>::test_static_template<void>(const char *volatile &, unsigned);
1392 
1393 struct bad_promise_deleted_constructor {
1394   // expected-note@+1 {{'bad_promise_deleted_constructor' has been explicitly marked deleted here}}
1395   bad_promise_deleted_constructor() = delete;
1396   coro<bad_promise_deleted_constructor> get_return_object();
1397   suspend_always initial_suspend();
1398   suspend_always final_suspend() noexcept;
1399   void return_void();
1400   void unhandled_exception();
1401 };
1402 
1403 coro<bad_promise_deleted_constructor>
1404 bad_coroutine_calls_deleted_promise_constructor() {
1405   // expected-error@-1 {{call to deleted constructor of 'std::coroutine_traits<coro<CoroHandleMemberFunctionTest::bad_promise_deleted_constructor>>::promise_type' (aka 'CoroHandleMemberFunctionTest::bad_promise_deleted_constructor')}}
1406   co_return;
1407 }
1408 
1409 // Test that, when the promise type has a constructor whose signature matches
1410 // that of the coroutine function, that constructor is used. If no matching
1411 // constructor exists, the default constructor is used as a fallback. If no
1412 // matching constructors exist at all, an error is emitted. This is an
1413 // experimental feature that will be proposed for the Coroutines TS.
1414 
1415 struct good_promise_default_constructor {
1416   good_promise_default_constructor(double, float, int);
1417   good_promise_default_constructor() = default;
1418   coro<good_promise_default_constructor> get_return_object();
1419   suspend_always initial_suspend();
1420   suspend_always final_suspend() noexcept;
1421   void return_void();
1422   void unhandled_exception();
1423 };
1424 
1425 coro<good_promise_default_constructor>
1426 good_coroutine_calls_default_constructor() {
1427   co_return;
1428 }
1429 
1430 struct some_class;
1431 
1432 struct good_promise_custom_constructor {
1433   good_promise_custom_constructor(some_class&, float, int);
1434   good_promise_custom_constructor(double, float, int);
1435   good_promise_custom_constructor() = delete;
1436   coro<good_promise_custom_constructor> get_return_object();
1437   suspend_always initial_suspend();
1438   suspend_always final_suspend() noexcept;
1439   void return_void();
1440   void unhandled_exception();
1441 };
1442 
1443 coro<good_promise_custom_constructor>
1444 good_coroutine_calls_custom_constructor(double, float, int) {
1445   co_return;
1446 }
1447 
1448 struct some_class {
1449   coro<good_promise_custom_constructor>
1450   good_coroutine_calls_custom_constructor(float, int) {
1451     co_return;
1452   }
1453   coro<good_promise_custom_constructor>
1454   static good_coroutine_calls_custom_constructor(double, float, int) {
1455     co_return;
1456   }
1457 };
1458 
1459 struct bad_promise_no_matching_constructor {
1460   bad_promise_no_matching_constructor(int, int, int);
1461   // expected-note@+1 2 {{'bad_promise_no_matching_constructor' has been explicitly marked deleted here}}
1462   bad_promise_no_matching_constructor() = delete;
1463   coro<bad_promise_no_matching_constructor> get_return_object();
1464   suspend_always initial_suspend();
1465   suspend_always final_suspend() noexcept;
1466   void return_void();
1467   void unhandled_exception();
1468 };
1469 
1470 coro<bad_promise_no_matching_constructor>
1471 bad_coroutine_calls_with_no_matching_constructor(int, int) {
1472   // expected-error@-1 {{call to deleted constructor of 'std::coroutine_traits<coro<CoroHandleMemberFunctionTest::bad_promise_no_matching_constructor>, int, int>::promise_type' (aka 'CoroHandleMemberFunctionTest::bad_promise_no_matching_constructor')}}
1473   co_return;
1474 }
1475 
1476 struct some_class2 {
1477 coro<bad_promise_no_matching_constructor>
1478 bad_coroutine_calls_with_no_matching_constructor(int, int, int) {
1479   // expected-error@-1 {{call to deleted constructor}}
1480   co_return;
1481 }
1482 };
1483 
1484 } // namespace CoroHandleMemberFunctionTest
1485 
1486 class awaitable_no_unused_warn {
1487 public:
1488   using handle_type = std::coroutine_handle<>;
1489   constexpr bool await_ready() noexcept { return false; }
1490   void await_suspend(handle_type) noexcept {}
1491   int await_resume() noexcept { return 1; }
1492 };
1493 
1494 
1495 class awaitable_unused_warn {
1496 public:
1497   using handle_type = std::coroutine_handle<>;
1498   constexpr bool await_ready() noexcept { return false; }
1499   void await_suspend(handle_type) noexcept {}
1500   [[nodiscard]] int await_resume() noexcept { return 1; }
1501 };
1502 
1503 template <class Await>
1504 struct check_warning_promise {
1505   coro<check_warning_promise> get_return_object();
1506   Await initial_suspend();
1507   Await final_suspend() noexcept;
1508   Await yield_value(int);
1509   void return_void();
1510   void unhandled_exception();
1511 };
1512 
1513 
1514 coro<check_warning_promise<awaitable_no_unused_warn>>
1515 test_no_unused_warning() {
1516   co_await awaitable_no_unused_warn();
1517   co_yield 42;
1518 }
1519 
1520 coro<check_warning_promise<awaitable_unused_warn>>
1521 test_unused_warning() {
1522   co_await awaitable_unused_warn(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
1523   co_yield 42; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
1524 }
1525 
1526 struct missing_await_ready {
1527   void await_suspend(std::coroutine_handle<>);
1528   void await_resume();
1529 };
1530 struct missing_await_suspend {
1531   bool await_ready();
1532   void await_resume();
1533 };
1534 struct missing_await_resume {
1535   bool await_ready();
1536   void await_suspend(std::coroutine_handle<>);
1537 };
1538 
1539 void test_missing_awaitable_members() {
1540   co_await missing_await_ready{}; // expected-error {{no member named 'await_ready' in 'missing_await_ready'}}
1541   co_await missing_await_suspend{}; // expected-error {{no member named 'await_suspend' in 'missing_await_suspend'}}
1542   co_await missing_await_resume{}; // expected-error {{no member named 'await_resume' in 'missing_await_resume'}}
1543 }
1544 
1545 __attribute__((__always_inline__))
1546 void warn_always_inline() { // expected-warning {{this coroutine may be split into pieces; not every piece is guaranteed to be inlined}}
1547   co_await suspend_always{};
1548 }
1549 
1550 [[gnu::always_inline]]
1551 void warn_gnu_always_inline() { // expected-warning {{this coroutine may be split into pieces; not every piece is guaranteed to be inlined}}
1552   co_await suspend_always{};
1553 }
1554