[lld][WebAssembly] Reinstate mistakenly disabled test. NFC
[llvm-project.git] / clang / test / SemaCXX / coroutines.cpp
blobb461c881355b599475dd8f369c3690a2e2490cea
1 // This file contains references to sections of the Coroutines TS, which can be
2 // found at http://wg21.link/coroutines.
4 // RUN: %clang_cc1 -std=c++2b -fsyntax-only -verify=expected,cxx20_2b,cxx2b %s -fcxx-exceptions -fexceptions -Wunused-result
5 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected,cxx14_20,cxx20_2b %s -fcxx-exceptions -fexceptions -Wunused-result
7 void no_coroutine_traits_bad_arg_await() {
8 co_await a; // expected-error {{include <coroutine>}}
9 // expected-error@-1 {{use of undeclared identifier 'a'}}
12 void no_coroutine_traits_bad_arg_yield() {
13 co_yield a; // expected-error {{include <coroutine>}}
14 // expected-error@-1 {{use of undeclared identifier 'a'}}
18 void no_coroutine_traits_bad_arg_return() {
19 co_return a; // expected-error {{include <coroutine>}}
20 // expected-error@-1 {{use of undeclared identifier 'a'}}
23 void no_coroutine_traits() {
24 co_await 4; // expected-error {{std::coroutine_traits type was not found; include <coroutine>}}
27 namespace std {
29 template <class... Args>
30 struct void_t_imp {
31 using type = void;
33 template <class... Args>
34 using void_t = typename void_t_imp<Args...>::type;
36 template <class T, class = void>
37 struct traits_sfinae_base {};
39 template <class T>
40 struct traits_sfinae_base<T, void_t<typename T::promise_type>> {
41 using promise_type = typename T::promise_type;
44 template <class Ret, class... Args>
45 struct coroutine_traits : public traits_sfinae_base<Ret> {};
46 } // end of namespace std
48 template<typename Promise> struct coro {};
49 template <typename Promise, typename... Ps>
50 struct std::coroutine_traits<coro<Promise>, Ps...> {
51 using promise_type = Promise;
54 struct awaitable {
55 bool await_ready() noexcept;
56 template <typename F>
57 void await_suspend(F) noexcept;
58 void await_resume() noexcept;
59 } a;
61 struct suspend_always {
62 bool await_ready() noexcept { return false; }
63 template <typename F>
64 void await_suspend(F) noexcept;
65 void await_resume() noexcept {}
68 struct suspend_never {
69 bool await_ready() noexcept { return true; }
70 template <typename F>
71 void await_suspend(F) noexcept;
72 void await_resume() noexcept {}
75 struct auto_await_suspend {
76 bool await_ready();
77 template <typename F> auto await_suspend(F) {}
78 void await_resume();
81 struct DummyVoidTag {};
82 DummyVoidTag no_specialization() { // expected-error {{this function cannot be a coroutine: 'std::coroutine_traits<DummyVoidTag>' has no member named 'promise_type'}}
83 co_await a;
86 template <typename... T>
87 struct std::coroutine_traits<int, T...> {};
89 int no_promise_type() { // expected-error {{this function cannot be a coroutine: 'std::coroutine_traits<int>' has no member named 'promise_type'}}
90 co_await a;
93 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'}}
94 co_await a;
95 co_await a;
98 template <>
99 struct std::coroutine_traits<double, double> { typedef int promise_type; };
100 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}}
101 co_await a;
104 template <>
105 struct std::coroutine_traits<double, int> {
106 struct promise_type {};
108 double bad_promise_type_2(int) { // expected-error {{no member named 'initial_suspend'}}
109 co_yield 0; // expected-error {{no member named 'yield_value' in 'std::coroutine_traits<double, int>::promise_type'}}
112 struct promise; // expected-note {{forward declaration}}
113 struct promise_void;
114 struct void_tag {};
115 template <typename... T>
116 struct std::coroutine_traits<void, T...> { using promise_type = promise; };
117 template <typename... T>
118 struct std::coroutine_traits<void, void_tag, T...> { using promise_type = promise_void; };
120 // FIXME: This diagnostic is terrible.
121 void undefined_promise() { // expected-error {{this function cannot be a coroutine: 'std::coroutine_traits<void>::promise_type' (aka 'promise') is an incomplete type}}
122 co_await a;
125 struct yielded_thing { const char *p; short a, b; };
127 struct not_awaitable {};
129 struct promise {
130 void get_return_object();
131 suspend_always initial_suspend();
132 suspend_always final_suspend() noexcept;
133 awaitable yield_value(int); // expected-note 2{{candidate}}
134 awaitable yield_value(yielded_thing); // expected-note 2{{candidate}}
135 not_awaitable yield_value(void()); // expected-note 2{{candidate}}
136 void return_value(int); // expected-note 2{{here}}
137 void unhandled_exception();
140 struct promise_void {
141 void get_return_object();
142 suspend_always initial_suspend();
143 suspend_always final_suspend() noexcept;
144 void return_void();
145 void unhandled_exception();
148 void no_coroutine_handle() { // expected-error {{std::coroutine_handle type was not found; include <coroutine> before defining a coroutine}}
149 //expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
150 co_return 5; //expected-note {{function is a coroutine due to use of 'co_return' here}}
153 namespace std {
154 template <class PromiseType = void>
155 struct coroutine_handle {
156 static coroutine_handle from_address(void *) noexcept;
158 template <>
159 struct coroutine_handle<void> {
160 template <class PromiseType>
161 coroutine_handle(coroutine_handle<PromiseType>) noexcept;
162 static coroutine_handle from_address(void *) noexcept;
164 } // namespace std
166 void yield() {
167 co_yield 0;
168 co_yield {"foo", 1, 2};
169 co_yield {1e100}; // expected-error {{cannot be narrowed}} expected-note {{explicit cast}} expected-warning {{implicit conversion}} expected-warning {{braces around scalar}}
170 co_yield {"foo", __LONG_LONG_MAX__}; // expected-error {{cannot be narrowed}} expected-note {{explicit cast}} expected-warning {{changes value}}
171 co_yield {"foo"};
172 co_yield "foo"; // expected-error {{no matching}}
173 co_yield 1.0;
174 co_yield yield; // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
177 void check_auto_await_suspend() {
178 co_await auto_await_suspend{}; // Should compile successfully.
181 void coreturn(int n) {
182 co_await a;
183 if (n == 0)
184 co_return 3;
185 if (n == 1)
186 co_return {4}; // expected-warning {{braces around scalar initializer}}
187 if (n == 2)
188 co_return "foo"; // expected-error {{cannot initialize a parameter of type 'int' with an lvalue of type 'const char[4]'}}
189 co_return 42;
192 template <class T>
193 void co_await_non_dependent_arg(T) {
194 co_await a;
196 template void co_await_non_dependent_arg(int);
198 void mixed_yield() {
199 co_yield 0; // expected-note {{use of 'co_yield'}}
200 return; // expected-error {{not allowed in coroutine}}
203 void mixed_yield_invalid() {
204 co_yield blah; // expected-error {{use of undeclared identifier}}
205 // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}}
206 return; // expected-error {{return statement not allowed in coroutine}}
209 template <class T>
210 void mixed_yield_template(T) {
211 co_yield blah; // expected-error {{use of undeclared identifier}}
212 // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}}
213 return; // expected-error {{return statement not allowed in coroutine}}
216 template <class T>
217 void mixed_yield_template2(T) {
218 co_yield 42;
219 // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}}
220 return; // expected-error {{return statement not allowed in coroutine}}
223 template <class T>
224 void mixed_yield_template3(T v) {
225 co_yield blah(v);
226 // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}}
227 return; // expected-error {{return statement not allowed in coroutine}}
230 void mixed_await() {
231 co_await a; // expected-note {{use of 'co_await'}}
232 return; // expected-error {{not allowed in coroutine}}
235 void mixed_await_invalid() {
236 co_await 42; // expected-error {{'int' is not a structure or union}}
237 // expected-note@-1 {{function is a coroutine due to use of 'co_await'}}
238 return; // expected-error {{not allowed in coroutine}}
241 template <class T>
242 void mixed_await_template(T) {
243 co_await 42;
244 // expected-note@-1 {{function is a coroutine due to use of 'co_await'}}
245 return; // expected-error {{not allowed in coroutine}}
248 template <class T>
249 void mixed_await_template2(T v) {
250 co_await v; // expected-error {{'long' is not a structure or union}}
251 // expected-note@-1 {{function is a coroutine due to use of 'co_await'}}
252 return; // expected-error {{not allowed in coroutine}}
254 template void mixed_await_template2(long); // expected-note {{requested here}}
256 void only_coreturn(void_tag) {
257 co_return; // OK
260 void mixed_coreturn(void_tag, bool b) {
261 if (b)
262 co_return; // expected-note {{use of 'co_return'}}
263 else
264 return; // expected-error {{not allowed in coroutine}}
267 void mixed_coreturn_invalid(bool b) {
268 if (b)
269 co_return; // expected-note {{use of 'co_return'}}
270 // expected-error@-1 {{no member named 'return_void' in 'promise'}}
271 else
272 return; // expected-error {{not allowed in coroutine}}
275 template <class T>
276 void mixed_coreturn_template(void_tag, bool b, T v) {
277 if (b)
278 co_return v; // expected-note {{use of 'co_return'}}
279 // expected-error@-1 {{no member named 'return_value' in 'promise_void'}}
280 else
281 return; // expected-error {{not allowed in coroutine}}
283 template void mixed_coreturn_template(void_tag, bool, int); // expected-note {{requested here}}
285 template <class T>
286 void mixed_coreturn_template2(bool b, T) {
287 if (b)
288 co_return v; // expected-note {{use of 'co_return'}}
289 // expected-error@-1 {{use of undeclared identifier 'v'}}
290 else
291 return; // expected-error {{not allowed in coroutine}}
294 struct CtorDtor {
295 CtorDtor() {
296 co_yield 0; // expected-error {{'co_yield' cannot be used in a constructor}}
298 CtorDtor(awaitable a) {
299 // The spec doesn't say this is ill-formed, but it must be.
300 co_await a; // expected-error {{'co_await' cannot be used in a constructor}}
302 ~CtorDtor() {
303 co_return 0; // expected-error {{'co_return' cannot be used in a destructor}}
305 void operator=(CtorDtor&) {
306 co_yield 0; // OK.
308 void operator=(CtorDtor const &) {
309 co_yield 0; // OK.
311 void operator=(CtorDtor &&) {
312 co_await a; // OK.
314 void operator=(CtorDtor const &&) {
315 co_await a; // OK.
317 void operator=(int) {
318 co_await a; // OK. Not a special member
322 namespace std { class type_info; }
324 void unevaluated() {
325 decltype(co_await a); // expected-error {{'co_await' cannot be used in an unevaluated context}}
326 // expected-warning@-1 {{declaration does not declare anything}}
327 sizeof(co_await a); // expected-error {{'co_await' cannot be used in an unevaluated context}}
328 // expected-error@-1 {{invalid application of 'sizeof' to an incomplete type 'void'}}
329 // expected-warning@-2 {{expression with side effects has no effect in an unevaluated context}}
330 typeid(co_await a); // expected-error {{'co_await' cannot be used in an unevaluated context}}
331 // expected-warning@-1 {{expression with side effects has no effect in an unevaluated context}}
332 // expected-warning@-2 {{expression result unused}}
333 decltype(co_yield 1); // expected-error {{'co_yield' cannot be used in an unevaluated context}}
334 // expected-warning@-1 {{declaration does not declare anything}}
335 sizeof(co_yield 2); // expected-error {{'co_yield' cannot be used in an unevaluated context}}
336 // expected-error@-1 {{invalid application of 'sizeof' to an incomplete type 'void'}}
337 // expected-warning@-2 {{expression with side effects has no effect in an unevaluated context}}
338 typeid(co_yield 3); // expected-error {{'co_yield' cannot be used in an unevaluated context}}
339 // expected-warning@-1 {{expression with side effects has no effect in an unevaluated context}}
340 // expected-warning@-2 {{expression result unused}}
343 // [expr.await]p2: "An await-expression shall not appear in a default argument."
344 // FIXME: A better diagnostic would explicitly state that default arguments are
345 // not allowed. A user may not understand that this is "outside a function."
346 void default_argument(int arg = co_await 0) {} // expected-error {{'co_await' cannot be used outside a function}}
348 void await_in_catch_coroutine() {
349 try {
350 } catch (...) { // FIXME: Emit a note diagnostic pointing out the try handler on this line.
351 []() -> void { co_await a; }(); // OK
352 co_await a; // expected-error {{'co_await' cannot be used in the handler of a try block}}
356 void await_nested_in_catch_coroutine() {
357 try {
358 } catch (...) { // FIXME: Emit a note diagnostic pointing out the try handler on this line.
359 try {
360 co_await a; // expected-error {{'co_await' cannot be used in the handler of a try block}}
361 []() -> void { co_await a; }(); // OK
362 } catch (...) {
363 co_return 123;
368 void await_in_lambda_in_catch_coroutine() {
369 try {
370 } catch (...) {
371 []() -> void { co_await a; }(); // OK
375 void yield_in_catch_coroutine() {
376 try {
377 } catch (...) {
378 co_yield 1; // expected-error {{'co_yield' cannot be used in the handler of a try block}}
382 void return_in_catch_coroutine() {
383 try {
384 } catch (...) {
385 co_return 123; // OK
389 constexpr auto constexpr_deduced_return_coroutine() {
390 co_yield 0; // expected-error {{'co_yield' cannot be used in a constexpr function}}
391 // expected-error@-1 {{'co_yield' cannot be used in a function with a deduced return type}}
394 void varargs_coroutine(const char *, ...) {
395 co_await a; // expected-error {{'co_await' cannot be used in a varargs function}}
398 auto deduced_return_coroutine() {
399 co_await a; // expected-error {{'co_await' cannot be used in a function with a deduced return type}}
402 struct outer {};
403 struct await_arg_1 {};
404 struct await_arg_2 {};
406 namespace adl_ns {
407 struct coawait_arg_type {};
408 awaitable operator co_await(coawait_arg_type) noexcept;
411 namespace dependent_operator_co_await_lookup {
412 template<typename T> void await_template(T t) {
413 // no unqualified lookup results
414 co_await t; // expected-error {{no member named 'await_ready' in 'dependent_operator_co_await_lookup::not_awaitable'}}
415 // expected-error@-1 {{call to function 'operator co_await' that is neither visible in the template definition nor found by argument-dependent lookup}}
417 template void await_template(awaitable);
419 struct indirectly_awaitable { indirectly_awaitable(outer); };
420 awaitable operator co_await(indirectly_awaitable); // expected-note {{should be declared prior to}}
421 template void await_template(indirectly_awaitable);
423 struct not_awaitable {};
424 template void await_template(not_awaitable); // expected-note {{instantiation}}
426 template<typename T> void await_template_2(T t) {
427 // one unqualified lookup result
428 co_await t;
430 template void await_template(outer); // expected-note {{instantiation}}
431 template void await_template_2(outer);
433 struct transform_awaitable {};
434 struct transformed {};
436 struct transform_promise {
437 typedef transform_awaitable await_arg;
438 coro<transform_promise> get_return_object();
439 transformed initial_suspend();
440 ::adl_ns::coawait_arg_type final_suspend() noexcept;
441 transformed await_transform(transform_awaitable);
442 void unhandled_exception();
443 void return_void();
445 template <class AwaitArg>
446 struct basic_promise {
447 typedef AwaitArg await_arg;
448 coro<basic_promise> get_return_object();
449 awaitable initial_suspend();
450 awaitable final_suspend() noexcept;
451 void unhandled_exception();
452 void return_void();
455 awaitable operator co_await(await_arg_1);
457 template <typename T, typename U>
458 coro<T> await_template_3(U t) {
459 co_await t;
462 template coro<basic_promise<await_arg_1>> await_template_3<basic_promise<await_arg_1>>(await_arg_1);
464 template <class T, int I = 0>
465 struct dependent_member {
466 coro<T> mem_fn() const {
467 co_await typename T::await_arg{}; // expected-error {{call to function 'operator co_await'}}}
469 template <class U>
470 coro<T> dep_mem_fn(U t) {
471 co_await t;
475 template <>
476 struct dependent_member<long> {
477 // FIXME this diagnostic is terrible
478 coro<transform_promise> mem_fn() const { // expected-error {{no member named 'await_ready' in 'dependent_operator_co_await_lookup::transformed'}}
479 // expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
480 // expected-note@+1 {{function is a coroutine due to use of 'co_await' here}}
481 co_await transform_awaitable{};
482 // expected-error@-1 {{no member named 'await_ready'}}
484 template <class R, class U>
485 coro<R> dep_mem_fn(U u) { co_await u; }
488 awaitable operator co_await(await_arg_2); // expected-note {{'operator co_await' should be declared prior to the call site}}
490 template struct dependent_member<basic_promise<await_arg_1>, 0>;
491 template struct dependent_member<basic_promise<await_arg_2>, 0>; // expected-note {{in instantiation}}
493 template <>
494 coro<transform_promise>
495 // FIXME this diagnostic is terrible
496 dependent_member<long>::dep_mem_fn<transform_promise>(int) { // expected-error {{no member named 'await_ready' in 'dependent_operator_co_await_lookup::transformed'}}
497 //expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
498 //expected-note@+1 {{function is a coroutine due to use of 'co_await' here}}
499 co_await transform_awaitable{};
500 // expected-error@-1 {{no member named 'await_ready'}}
503 void operator co_await(transform_awaitable) = delete;
504 awaitable operator co_await(transformed);
506 template coro<transform_promise>
507 dependent_member<long>::dep_mem_fn<transform_promise>(transform_awaitable);
509 template <>
510 coro<transform_promise> dependent_member<long>::dep_mem_fn<transform_promise>(long) {
511 co_await transform_awaitable{};
514 template <>
515 struct dependent_member<int> {
516 coro<transform_promise> mem_fn() const {
517 co_await transform_awaitable{};
521 template coro<transform_promise> await_template_3<transform_promise>(transform_awaitable);
522 template struct dependent_member<transform_promise>;
523 template coro<transform_promise> dependent_member<transform_promise>::dep_mem_fn(transform_awaitable);
526 struct yield_fn_tag {};
527 template <>
528 struct std::coroutine_traits<void, yield_fn_tag> {
529 struct promise_type {
530 // FIXME: add an await_transform overload for functions
531 awaitable yield_value(int());
532 void return_value(int());
534 suspend_never initial_suspend();
535 suspend_never final_suspend() noexcept;
536 void get_return_object();
537 void unhandled_exception();
541 namespace placeholder {
542 awaitable f(), f(int); // expected-note 4{{possible target}}
543 int g(), g(int); // expected-note 2{{candidate}}
544 void x() {
545 co_await f; // expected-error {{reference to overloaded function}}
547 void y() {
548 co_yield g; // expected-error {{no matching member function for call to 'yield_value'}}
550 void z() {
551 co_await a;
552 co_return g; // expected-error {{address of overloaded function 'g' does not match required type 'int'}}
555 void x(yield_fn_tag) {
556 co_await f; // expected-error {{reference to overloaded function}}
558 void y(yield_fn_tag) {
559 co_yield g;
561 void z(yield_fn_tag) {
562 co_await a;
563 co_return g;
567 struct bad_promise_1 {
568 suspend_always initial_suspend();
569 suspend_always final_suspend() noexcept;
570 void unhandled_exception();
571 void return_void();
573 coro<bad_promise_1> missing_get_return_object() { // expected-error {{no member named 'get_return_object' in 'bad_promise_1'}}
574 co_await a;
577 struct bad_promise_2 {
578 coro<bad_promise_2> get_return_object();
579 suspend_always final_suspend() noexcept;
580 void unhandled_exception();
581 void return_void();
583 // FIXME: This shouldn't happen twice
584 coro<bad_promise_2> missing_initial_suspend() { // expected-error {{no member named 'initial_suspend' in 'bad_promise_2'}}
585 co_await a;
588 struct bad_promise_3 {
589 coro<bad_promise_3> get_return_object();
590 suspend_always initial_suspend();
591 void unhandled_exception();
592 void return_void();
594 coro<bad_promise_3> missing_final_suspend() noexcept { // expected-error {{no member named 'final_suspend' in 'bad_promise_3'}}
595 co_await a;
598 struct bad_promise_4 {
599 coro<bad_promise_4> get_return_object();
600 not_awaitable initial_suspend();
601 suspend_always final_suspend() noexcept;
602 void return_void();
604 // FIXME: This diagnostic is terrible.
605 coro<bad_promise_4> bad_initial_suspend() { // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
606 // expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
607 co_await a; // expected-note {{function is a coroutine due to use of 'co_await' here}}
610 struct bad_promise_5 {
611 coro<bad_promise_5> get_return_object();
612 suspend_always initial_suspend();
613 not_awaitable final_suspend() noexcept;
614 void return_void();
616 // FIXME: This diagnostic is terrible.
617 coro<bad_promise_5> bad_final_suspend() { // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
618 // expected-note@-1 {{call to 'final_suspend' implicitly required by the final suspend point}}
619 co_await a; // expected-note {{function is a coroutine due to use of 'co_await' here}}
622 struct bad_promise_6 {
623 coro<bad_promise_6> get_return_object();
624 suspend_always initial_suspend();
625 suspend_always final_suspend() noexcept;
626 void unhandled_exception();
627 void return_void(); // expected-note 2 {{member 'return_void' first declared here}}
628 void return_value(int) const; // expected-note 2 {{member 'return_value' first declared here}}
629 void return_value(int);
631 coro<bad_promise_6> bad_implicit_return() { // expected-error {{'bad_promise_6' declares both 'return_value' and 'return_void'}}
632 co_await a;
635 template <class T>
636 coro<T> bad_implicit_return_dependent(T) { // expected-error {{'bad_promise_6' declares both 'return_value' and 'return_void'}}
637 co_await a;
639 template coro<bad_promise_6> bad_implicit_return_dependent(bad_promise_6); // expected-note {{in instantiation}}
641 struct bad_promise_7 { // expected-note 2 {{defined here}}
642 coro<bad_promise_7> get_return_object();
643 suspend_always initial_suspend();
644 suspend_always final_suspend() noexcept;
645 void return_void();
647 coro<bad_promise_7> no_unhandled_exception() { // expected-error {{'bad_promise_7' is required to declare the member 'unhandled_exception()'}}
648 co_await a;
651 template <class T>
652 coro<T> no_unhandled_exception_dependent(T) { // expected-error {{'bad_promise_7' is required to declare the member 'unhandled_exception()'}}
653 co_await a;
655 template coro<bad_promise_7> no_unhandled_exception_dependent(bad_promise_7); // expected-note {{in instantiation}}
657 struct bad_promise_base {
658 private:
659 void return_void(); // expected-note 2 {{declared private here}}
661 struct bad_promise_8 : bad_promise_base {
662 coro<bad_promise_8> get_return_object();
663 suspend_always initial_suspend();
664 suspend_always final_suspend() noexcept;
665 void unhandled_exception() __attribute__((unavailable)); // expected-note 2 {{marked unavailable here}}
666 void unhandled_exception() const;
667 void unhandled_exception(void *) const;
669 coro<bad_promise_8> calls_unhandled_exception() {
670 // expected-error@-1 {{'unhandled_exception' is unavailable}}
671 // expected-error@-2 {{'return_void' is a private member}}
672 co_await a;
675 template <class T>
676 coro<T> calls_unhandled_exception_dependent(T) {
677 // expected-error@-1 {{'unhandled_exception' is unavailable}}
678 // expected-error@-2 {{'return_void' is a private member}}
679 co_await a;
681 template coro<bad_promise_8> calls_unhandled_exception_dependent(bad_promise_8); // expected-note {{in instantiation}}
683 struct bad_promise_9 {
684 coro<bad_promise_9> get_return_object();
685 suspend_always initial_suspend();
686 suspend_always final_suspend() noexcept;
687 void await_transform(void *);
688 awaitable await_transform(int) __attribute__((unavailable)); // expected-note {{explicitly marked unavailable}}
689 void return_void();
690 void unhandled_exception();
692 coro<bad_promise_9> calls_await_transform() {
693 co_await 42; // expected-error {{'await_transform' is unavailable}}
696 struct bad_promise_10 {
697 coro<bad_promise_10> get_return_object();
698 suspend_always initial_suspend();
699 suspend_always final_suspend() noexcept;
700 int await_transform;
701 void return_void();
702 void unhandled_exception();
704 coro<bad_promise_10> bad_coawait() {
705 // FIXME this diagnostic is terrible
706 co_await 42; // expected-error {{called object type 'int' is not a function or function pointer}}
707 // expected-note@-1 {{call to 'await_transform' implicitly required by 'co_await' here}}
710 struct call_operator {
711 template <class... Args>
712 awaitable operator()(Args...) const { return a; }
714 void ret_void();
715 struct good_promise_1 {
716 coro<good_promise_1> get_return_object();
717 suspend_always initial_suspend();
718 suspend_always final_suspend() noexcept;
719 void unhandled_exception();
720 static const call_operator await_transform;
721 using Fn = void (*)();
722 Fn return_void = ret_void;
724 const call_operator good_promise_1::await_transform;
725 coro<good_promise_1> ok_static_coawait() {
726 // FIXME this diagnostic is terrible
727 co_await 42;
730 template<typename T> void ok_generic_lambda_coawait_PR41909() {
731 [](auto& arg) -> coro<good_promise_1> { // expected-warning {{expression result unused}}
732 co_await 12;
734 [](auto &arg) -> coro<good_promise_1> {
735 co_await 24;
736 }("argument");
737 [](auto &arg) ->coro<good_promise_1> { // expected-warning {{expression result unused}}
738 []() -> coro<good_promise_1> {
739 co_await 36;
741 co_await 48;
744 template void ok_generic_lambda_coawait_PR41909<int>(); // expected-note {{in instantiation of function template specialization 'ok_generic_lambda_coawait_PR41909<int>' requested here}}
746 template <> struct std::coroutine_traits<int, int, const char **> { using promise_type = promise; };
748 int main(int, const char**) {
749 co_await a; // expected-error {{'co_await' cannot be used in the 'main' function}}
752 struct good_promise_2 {
753 float get_return_object();
754 suspend_always initial_suspend();
755 suspend_always final_suspend() noexcept;
756 void return_void();
757 void unhandled_exception();
759 template <> struct std::coroutine_handle<good_promise_2> {};
761 template <> struct std::coroutine_traits<float> { using promise_type = good_promise_2; };
763 float badly_specialized_coro_handle() { // expected-error {{std::coroutine_handle must have a member named 'from_address'}}
764 //expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
765 co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
768 namespace std {
769 struct nothrow_t {};
770 constexpr nothrow_t nothrow = {};
773 using SizeT = decltype(sizeof(int));
775 void* operator new(SizeT __sz, const std::nothrow_t&) noexcept;
776 void operator delete(void* __p, const std::nothrow_t&) noexcept;
780 struct promise_on_alloc_failure_tag {};
782 template <>
783 struct std::coroutine_traits<int, promise_on_alloc_failure_tag> {
784 struct promise_type {
785 int get_return_object() {}
786 suspend_always initial_suspend() { return {}; }
787 suspend_always final_suspend() noexcept { return {}; }
788 void return_void() {}
789 int get_return_object_on_allocation_failure(); // expected-error{{'promise_type': 'get_return_object_on_allocation_failure()' must be a static member function}}
790 void unhandled_exception();
794 extern "C" int f(promise_on_alloc_failure_tag) {
795 co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
798 struct bad_promise_11 {
799 coro<bad_promise_11> get_return_object();
800 suspend_always initial_suspend();
801 suspend_always final_suspend() noexcept;
802 void unhandled_exception();
803 void return_void();
805 private:
806 static coro<bad_promise_11> get_return_object_on_allocation_failure(); // expected-note 2 {{declared private here}}
808 coro<bad_promise_11> private_alloc_failure_handler() {
809 // expected-error@-1 {{'get_return_object_on_allocation_failure' is a private member of 'bad_promise_11'}}
810 co_return; // FIXME: Add a "declared coroutine here" note.
813 template <class T>
814 coro<T> dependent_private_alloc_failure_handler(T) {
815 // expected-error@-1 {{'get_return_object_on_allocation_failure' is a private member of 'bad_promise_11'}}
816 co_return; // FIXME: Add a "declared coroutine here" note.
818 template coro<bad_promise_11> dependent_private_alloc_failure_handler(bad_promise_11);
819 // expected-note@-1 {{requested here}}
821 struct bad_promise_12 {
822 coro<bad_promise_12> get_return_object();
823 suspend_always initial_suspend();
824 suspend_always final_suspend() noexcept;
825 void unhandled_exception();
826 void return_void();
827 static coro<bad_promise_12> get_return_object_on_allocation_failure();
829 static void* operator new(SizeT);
830 // 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()'}}
832 coro<bad_promise_12> throwing_in_class_new() { // expected-note {{call to 'operator new' implicitly required by coroutine function here}}
833 co_return;
836 template <class T>
837 coro<T> dependent_throwing_in_class_new(T) { // expected-note {{call to 'operator new' implicitly required by coroutine function here}}
838 co_return;
840 template coro<bad_promise_12> dependent_throwing_in_class_new(bad_promise_12); // expected-note {{requested here}}
843 struct good_promise_13 {
844 coro<good_promise_13> get_return_object();
845 suspend_always initial_suspend();
846 suspend_always final_suspend() noexcept;
847 void unhandled_exception();
848 void return_void();
849 static coro<good_promise_13> get_return_object_on_allocation_failure();
851 coro<good_promise_13> uses_nothrow_new() {
852 co_return;
855 template <class T>
856 coro<T> dependent_uses_nothrow_new(T) {
857 co_return;
859 template coro<good_promise_13> dependent_uses_nothrow_new(good_promise_13);
861 struct good_promise_custom_new_operator {
862 coro<good_promise_custom_new_operator> get_return_object();
863 suspend_always initial_suspend();
864 suspend_always final_suspend() noexcept;
865 void return_void();
866 void unhandled_exception();
867 void *operator new(SizeT, double, float, int);
870 coro<good_promise_custom_new_operator>
871 good_coroutine_calls_custom_new_operator(double, float, int) {
872 co_return;
875 struct coroutine_nonstatic_member_struct;
877 struct good_promise_nonstatic_member_custom_new_operator {
878 coro<good_promise_nonstatic_member_custom_new_operator> get_return_object();
879 suspend_always initial_suspend();
880 suspend_always final_suspend() noexcept;
881 void return_void();
882 void unhandled_exception();
883 void *operator new(SizeT, coroutine_nonstatic_member_struct &, double);
886 struct good_promise_noexcept_custom_new_operator {
887 static coro<good_promise_noexcept_custom_new_operator> get_return_object_on_allocation_failure();
888 coro<good_promise_noexcept_custom_new_operator> get_return_object();
889 suspend_always initial_suspend();
890 suspend_always final_suspend() noexcept;
891 void return_void();
892 void unhandled_exception();
893 void *operator new(SizeT, double, float, int) noexcept;
896 coro<good_promise_noexcept_custom_new_operator>
897 good_coroutine_calls_noexcept_custom_new_operator(double, float, int) {
898 co_return;
901 struct mismatch_gro_type_tag1 {};
902 template <>
903 struct std::coroutine_traits<int, mismatch_gro_type_tag1> {
904 struct promise_type {
905 void get_return_object() {} //expected-note {{member 'get_return_object' declared here}}
906 suspend_always initial_suspend() { return {}; }
907 suspend_always final_suspend() noexcept { return {}; }
908 void return_void() {}
909 void unhandled_exception();
913 extern "C" int f(mismatch_gro_type_tag1) {
914 // expected-error@-1 {{cannot initialize return object of type 'int' with an rvalue of type 'void'}}
915 co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
918 struct mismatch_gro_type_tag2 {};
919 template <>
920 struct std::coroutine_traits<int, mismatch_gro_type_tag2> {
921 struct promise_type {
922 void *get_return_object() {} //expected-note {{member 'get_return_object' declared here}}
923 suspend_always initial_suspend() { return {}; }
924 suspend_always final_suspend() noexcept { return {}; }
925 void return_void() {}
926 void unhandled_exception();
930 extern "C" int f(mismatch_gro_type_tag2) {
931 // cxx2b-error@-1 {{cannot initialize return object of type 'int' with an rvalue of type 'void *'}}
932 // cxx14_20-error@-2 {{cannot initialize return object of type 'int' with an lvalue of type 'void *'}}
933 co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
936 struct mismatch_gro_type_tag3 {};
937 template <>
938 struct std::coroutine_traits<int, mismatch_gro_type_tag3> {
939 struct promise_type {
940 int get_return_object() {}
941 static void get_return_object_on_allocation_failure() {} //expected-note {{member 'get_return_object_on_allocation_failure' declared here}}
942 suspend_always initial_suspend() { return {}; }
943 suspend_always final_suspend() noexcept { return {}; }
944 void return_void() {}
945 void unhandled_exception();
949 extern "C" int f(mismatch_gro_type_tag3) {
950 // expected-error@-1 {{cannot initialize return object of type 'int' with an rvalue of type 'void'}}
951 co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
955 struct mismatch_gro_type_tag4 {};
956 template <>
957 struct std::coroutine_traits<int, mismatch_gro_type_tag4> {
958 struct promise_type {
959 int get_return_object() {}
960 static char *get_return_object_on_allocation_failure() {} //expected-note {{member 'get_return_object_on_allocation_failure' declared}}
961 suspend_always initial_suspend() { return {}; }
962 suspend_always final_suspend() noexcept { return {}; }
963 void return_void() {}
964 void unhandled_exception();
968 extern "C" int f(mismatch_gro_type_tag4) {
969 // expected-error@-1 {{cannot initialize return object of type 'int' with an rvalue of type 'char *'}}
970 co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
973 struct promise_no_return_func {
974 coro<promise_no_return_func> get_return_object();
975 suspend_always initial_suspend();
976 suspend_always final_suspend() noexcept;
977 void unhandled_exception();
979 // [dcl.fct.def.coroutine]/p6
980 // If searches for the names return_­void and return_­value in the scope of
981 // the promise type each find any declarations, the program is ill-formed.
982 // [Note 1: If return_­void is found, flowing off the end of a coroutine is
983 // equivalent to a co_­return with no operand. Otherwise, flowing off the end
984 // of a coroutine results in undefined behavior ([stmt.return.coroutine]). —
985 // end note]
987 // So it isn't ill-formed if the promise doesn't define return_value and return_void.
988 // It is just a potential UB.
989 coro<promise_no_return_func> no_return_value_or_return_void() {
990 co_await a;
993 // The following two tests that it would emit correct diagnostic message
994 // if we co_return in `promise_no_return_func`.
995 coro<promise_no_return_func> no_return_value_or_return_void_2() {
996 co_return; // expected-error {{no member named 'return_void'}}
999 coro<promise_no_return_func> no_return_value_or_return_void_3() {
1000 co_return 43; // expected-error {{no member named 'return_value'}}
1003 struct bad_await_suspend_return {
1004 bool await_ready();
1005 // expected-error@+1 {{return type of 'await_suspend' is required to be 'void' or 'bool' (have 'char')}}
1006 char await_suspend(std::coroutine_handle<>);
1007 void await_resume();
1009 struct bad_await_ready_return {
1010 // expected-note@+1 {{return type of 'await_ready' is required to be contextually convertible to 'bool'}}
1011 void await_ready();
1012 bool await_suspend(std::coroutine_handle<>);
1013 void await_resume();
1015 struct await_ready_explicit_bool {
1016 struct BoolT {
1017 explicit operator bool() const;
1019 BoolT await_ready();
1020 void await_suspend(std::coroutine_handle<>);
1021 void await_resume();
1023 template <class SuspendTy>
1024 struct await_suspend_type_test {
1025 bool await_ready();
1026 // expected-error@+2 {{return type of 'await_suspend' is required to be 'void' or 'bool' (have 'bool &')}}
1027 // expected-error@+1 {{return type of 'await_suspend' is required to be 'void' or 'bool' (have 'bool &&')}}
1028 SuspendTy await_suspend(std::coroutine_handle<>);
1029 // cxx20_2b-warning@-1 {{volatile-qualified return type 'const volatile bool' is deprecated}}
1030 void await_resume();
1032 void test_bad_suspend() {
1034 // FIXME: The actual error emitted here is terrible, and no number of notes can save it.
1035 bad_await_ready_return a;
1036 // expected-error@+1 {{value of type 'void' is not contextually convertible to 'bool'}}
1037 co_await a; // expected-note {{call to 'await_ready' implicitly required by coroutine function here}}
1040 bad_await_suspend_return b;
1041 co_await b; // expected-note {{call to 'await_suspend' implicitly required by coroutine function here}}
1044 await_ready_explicit_bool c;
1045 co_await c; // OK
1048 await_suspend_type_test<bool &&> a;
1049 await_suspend_type_test<bool &> b;
1050 await_suspend_type_test<const void> c;
1051 await_suspend_type_test<const volatile bool> d; // cxx20_2b-note {{in instantiation of template class}}
1052 co_await a; // expected-note {{call to 'await_suspend' implicitly required by coroutine function here}}
1053 co_await b; // expected-note {{call to 'await_suspend' implicitly required by coroutine function here}}
1054 co_await c; // OK
1055 co_await d; // OK
1059 template <int ID = 0>
1060 struct NoCopy {
1061 NoCopy(NoCopy const&) = delete; // expected-note 2 {{deleted here}}
1063 template <class T, class U>
1064 void test_dependent_param(T t, U) {
1065 // expected-error@-1 {{call to deleted constructor of 'NoCopy<0>'}}
1066 // expected-error@-2 {{call to deleted constructor of 'NoCopy<1>'}}
1067 ((void)t);
1068 co_return 42;
1070 template void test_dependent_param(NoCopy<0>, NoCopy<1>); // expected-note {{requested here}}
1072 namespace CoroHandleMemberFunctionTest {
1073 struct CoroMemberTag {};
1074 struct BadCoroMemberTag {};
1076 template <class T, class U>
1077 constexpr bool IsSameV = false;
1078 template <class T>
1079 constexpr bool IsSameV<T, T> = true;
1081 template <class T>
1082 struct TypeTest {
1083 template <class U>
1084 static constexpr bool IsSame = IsSameV<T, U>;
1086 template <class... Args>
1087 static constexpr bool MatchesArgs = IsSameV<T,
1088 std::coroutine_traits<CoroMemberTag, Args...>>;
1091 template <class T>
1092 struct AwaitReturnsType {
1093 bool await_ready() const;
1094 void await_suspend(...) const;
1095 T await_resume() const;
1098 template <class... CoroTraitsArgs>
1099 struct CoroMemberPromise {
1100 using TraitsT = std::coroutine_traits<CoroTraitsArgs...>;
1101 using TypeTestT = TypeTest<TraitsT>;
1102 using AwaitTestT = AwaitReturnsType<TypeTestT>;
1104 CoroMemberTag get_return_object();
1105 suspend_always initial_suspend();
1106 suspend_always final_suspend() noexcept;
1108 AwaitTestT yield_value(int);
1110 void return_void();
1111 void unhandled_exception();
1114 } // namespace CoroHandleMemberFunctionTest
1116 template <class... Args>
1117 struct ::std::coroutine_traits<CoroHandleMemberFunctionTest::CoroMemberTag, Args...> {
1118 using promise_type = CoroHandleMemberFunctionTest::CoroMemberPromise<CoroHandleMemberFunctionTest::CoroMemberTag, Args...>;
1121 namespace CoroHandleMemberFunctionTest {
1122 struct TestType {
1124 CoroMemberTag test_qual() {
1125 auto TC = co_yield 0;
1126 static_assert(TC.MatchesArgs<TestType &>, "");
1127 static_assert(!TC.MatchesArgs<TestType>, "");
1128 static_assert(!TC.MatchesArgs<TestType *>, "");
1131 CoroMemberTag test_asserts(int *) const {
1132 auto TC = co_yield 0;
1133 static_assert(TC.MatchesArgs<const TestType &>, ""); // expected-error {{static_assert failed}}
1134 static_assert(TC.MatchesArgs<const TestType &>, ""); // expected-error {{static_assert failed}}
1135 static_assert(TC.MatchesArgs<const TestType &, int *>, "");
1138 CoroMemberTag test_qual(int *, const float &&, volatile void *volatile) const {
1139 // cxx20_2b-warning@-1 {{volatile-qualified parameter type}}
1140 auto TC = co_yield 0;
1141 static_assert(TC.MatchesArgs<const TestType &, int *, const float &&, volatile void *volatile>, "");
1144 CoroMemberTag test_qual() const volatile {
1145 auto TC = co_yield 0;
1146 static_assert(TC.MatchesArgs<const volatile TestType &>, "");
1149 CoroMemberTag test_ref_qual() & {
1150 auto TC = co_yield 0;
1151 static_assert(TC.MatchesArgs<TestType &>, "");
1153 CoroMemberTag test_ref_qual() const & {
1154 auto TC = co_yield 0;
1155 static_assert(TC.MatchesArgs<TestType const &>, "");
1157 CoroMemberTag test_ref_qual() && {
1158 auto TC = co_yield 0;
1159 static_assert(TC.MatchesArgs<TestType &&>, "");
1161 CoroMemberTag test_ref_qual(const char *&) const volatile && {
1162 auto TC = co_yield 0;
1163 static_assert(TC.MatchesArgs<TestType const volatile &&, const char *&>, "");
1166 CoroMemberTag test_args(int) {
1167 auto TC = co_yield 0;
1168 static_assert(TC.MatchesArgs<TestType &, int>, "");
1170 CoroMemberTag test_args(int, long &, void *) const {
1171 auto TC = co_yield 0;
1172 static_assert(TC.MatchesArgs<TestType const &, int, long &, void *>, "");
1175 template <class... Args>
1176 CoroMemberTag test_member_template(Args...) const && {
1177 auto TC = co_yield 0;
1178 static_assert(TC.template MatchesArgs<TestType const &&, Args...>, "");
1181 static CoroMemberTag test_static() {
1182 auto TC = co_yield 0;
1183 static_assert(TC.MatchesArgs<>, "");
1184 static_assert(!TC.MatchesArgs<TestType>, "");
1185 static_assert(!TC.MatchesArgs<TestType &>, "");
1186 static_assert(!TC.MatchesArgs<TestType *>, "");
1189 static CoroMemberTag test_static(volatile void *const, char &&) {
1190 auto TC = co_yield 0;
1191 static_assert(TC.MatchesArgs<volatile void *const, char &&>, "");
1194 template <class Dummy>
1195 static CoroMemberTag test_static_template(const char *volatile &, unsigned) {
1196 auto TC = co_yield 0;
1197 using TCT = decltype(TC);
1198 static_assert(TCT::MatchesArgs<const char *volatile &, unsigned>, "");
1199 static_assert(!TCT::MatchesArgs<TestType &, const char *volatile &, unsigned>, "");
1202 BadCoroMemberTag test_diagnostics() {
1203 // expected-error@-1 {{this function cannot be a coroutine: 'std::coroutine_traits<CoroHandleMemberFunctionTest::BadCoroMemberTag, CoroHandleMemberFunctionTest::TestType &>' has no member named 'promise_type'}}
1204 co_return;
1206 BadCoroMemberTag test_diagnostics(int) const && {
1207 // expected-error@-1 {{this function cannot be a coroutine: 'std::coroutine_traits<CoroHandleMemberFunctionTest::BadCoroMemberTag, const CoroHandleMemberFunctionTest::TestType &&, int>' has no member named 'promise_type'}}
1208 co_return;
1211 static BadCoroMemberTag test_static_diagnostics(long *) {
1212 // expected-error@-1 {{this function cannot be a coroutine: 'std::coroutine_traits<CoroHandleMemberFunctionTest::BadCoroMemberTag, long *>' has no member named 'promise_type'}}
1213 co_return;
1217 template CoroMemberTag TestType::test_member_template(long, const char *) const &&;
1218 template CoroMemberTag TestType::test_static_template<void>(const char *volatile &, unsigned);
1220 template <class... Args>
1221 struct DepTestType {
1223 CoroMemberTag test_asserts(int *) const {
1224 auto TC = co_yield 0;
1225 static_assert(TC.template MatchesArgs<const DepTestType &>, ""); // expected-error {{static_assert failed}}
1226 static_assert(TC.template MatchesArgs<>, ""); // expected-error {{static_assert failed}}
1227 static_assert(TC.template MatchesArgs<const DepTestType &, int *>, "");
1230 CoroMemberTag test_qual() {
1231 auto TC = co_yield 0;
1232 static_assert(TC.template MatchesArgs<DepTestType &>, "");
1233 static_assert(!TC.template MatchesArgs<DepTestType>, "");
1234 static_assert(!TC.template MatchesArgs<DepTestType *>, "");
1237 CoroMemberTag test_qual(int *, const float &&, volatile void *volatile) const {
1238 // cxx20_2b-warning@-1 {{volatile-qualified parameter type}}
1239 auto TC = co_yield 0;
1240 static_assert(TC.template MatchesArgs<const DepTestType &, int *, const float &&, volatile void *volatile>, "");
1243 CoroMemberTag test_qual() const volatile {
1244 auto TC = co_yield 0;
1245 static_assert(TC.template MatchesArgs<const volatile DepTestType &>, "");
1248 CoroMemberTag test_ref_qual() & {
1249 auto TC = co_yield 0;
1250 static_assert(TC.template MatchesArgs<DepTestType &>, "");
1252 CoroMemberTag test_ref_qual() const & {
1253 auto TC = co_yield 0;
1254 static_assert(TC.template MatchesArgs<DepTestType const &>, "");
1256 CoroMemberTag test_ref_qual() && {
1257 auto TC = co_yield 0;
1258 static_assert(TC.template MatchesArgs<DepTestType &&>, "");
1260 CoroMemberTag test_ref_qual(const char *&) const volatile && {
1261 auto TC = co_yield 0;
1262 static_assert(TC.template MatchesArgs<DepTestType const volatile &&, const char *&>, "");
1265 CoroMemberTag test_args(int) {
1266 auto TC = co_yield 0;
1267 static_assert(TC.template MatchesArgs<DepTestType &, int>, "");
1269 CoroMemberTag test_args(int, long &, void *) const {
1270 auto TC = co_yield 0;
1271 static_assert(TC.template MatchesArgs<DepTestType const &, int, long &, void *>, "");
1274 template <class... UArgs>
1275 CoroMemberTag test_member_template(UArgs...) const && {
1276 auto TC = co_yield 0;
1277 static_assert(TC.template MatchesArgs<DepTestType const &&, UArgs...>, "");
1280 static CoroMemberTag test_static() {
1281 auto TC = co_yield 0;
1282 using TCT = decltype(TC);
1283 static_assert(TCT::MatchesArgs<>, "");
1284 static_assert(!TCT::MatchesArgs<DepTestType>, "");
1285 static_assert(!TCT::MatchesArgs<DepTestType &>, "");
1286 static_assert(!TCT::MatchesArgs<DepTestType *>, "");
1288 // Ensure diagnostics are actually being generated here
1289 static_assert(TCT::MatchesArgs<int>, ""); // expected-error {{static_assert failed}}
1292 static CoroMemberTag test_static(volatile void *const, char &&) {
1293 auto TC = co_yield 0;
1294 using TCT = decltype(TC);
1295 static_assert(TCT::MatchesArgs<volatile void *const, char &&>, "");
1298 template <class Dummy>
1299 static CoroMemberTag test_static_template(const char *volatile &, unsigned) {
1300 auto TC = co_yield 0;
1301 using TCT = decltype(TC);
1302 static_assert(TCT::MatchesArgs<const char *volatile &, unsigned>, "");
1303 static_assert(!TCT::MatchesArgs<DepTestType &, const char *volatile &, unsigned>, "");
1307 template struct DepTestType<int>; // expected-note {{requested here}}
1308 template CoroMemberTag DepTestType<int>::test_member_template(long, const char *) const &&;
1310 template CoroMemberTag DepTestType<int>::test_static_template<void>(const char *volatile &, unsigned);
1312 struct bad_promise_deleted_constructor {
1313 // expected-note@+1 {{'bad_promise_deleted_constructor' has been explicitly marked deleted here}}
1314 bad_promise_deleted_constructor() = delete;
1315 coro<bad_promise_deleted_constructor> get_return_object();
1316 suspend_always initial_suspend();
1317 suspend_always final_suspend() noexcept;
1318 void return_void();
1319 void unhandled_exception();
1322 coro<bad_promise_deleted_constructor>
1323 bad_coroutine_calls_deleted_promise_constructor() {
1324 // 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')}}
1325 co_return;
1328 // Test that, when the promise type has a constructor whose signature matches
1329 // that of the coroutine function, that constructor is used. If no matching
1330 // constructor exists, the default constructor is used as a fallback. If no
1331 // matching constructors exist at all, an error is emitted. This is an
1332 // experimental feature that will be proposed for the Coroutines TS.
1334 struct good_promise_default_constructor {
1335 good_promise_default_constructor(double, float, int);
1336 good_promise_default_constructor() = default;
1337 coro<good_promise_default_constructor> get_return_object();
1338 suspend_always initial_suspend();
1339 suspend_always final_suspend() noexcept;
1340 void return_void();
1341 void unhandled_exception();
1344 coro<good_promise_default_constructor>
1345 good_coroutine_calls_default_constructor() {
1346 co_return;
1349 struct some_class;
1351 struct good_promise_custom_constructor {
1352 good_promise_custom_constructor(some_class&, float, int);
1353 good_promise_custom_constructor(double, float, int);
1354 good_promise_custom_constructor() = delete;
1355 coro<good_promise_custom_constructor> get_return_object();
1356 suspend_always initial_suspend();
1357 suspend_always final_suspend() noexcept;
1358 void return_void();
1359 void unhandled_exception();
1362 coro<good_promise_custom_constructor>
1363 good_coroutine_calls_custom_constructor(double, float, int) {
1364 co_return;
1367 struct some_class {
1368 coro<good_promise_custom_constructor>
1369 good_coroutine_calls_custom_constructor(float, int) {
1370 co_return;
1372 coro<good_promise_custom_constructor>
1373 static good_coroutine_calls_custom_constructor(double, float, int) {
1374 co_return;
1378 struct bad_promise_no_matching_constructor {
1379 bad_promise_no_matching_constructor(int, int, int);
1380 // expected-note@+1 2 {{'bad_promise_no_matching_constructor' has been explicitly marked deleted here}}
1381 bad_promise_no_matching_constructor() = delete;
1382 coro<bad_promise_no_matching_constructor> get_return_object();
1383 suspend_always initial_suspend();
1384 suspend_always final_suspend() noexcept;
1385 void return_void();
1386 void unhandled_exception();
1389 coro<bad_promise_no_matching_constructor>
1390 bad_coroutine_calls_with_no_matching_constructor(int, int) {
1391 // 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')}}
1392 co_return;
1395 struct some_class2 {
1396 coro<bad_promise_no_matching_constructor>
1397 bad_coroutine_calls_with_no_matching_constructor(int, int, int) {
1398 // expected-error@-1 {{call to deleted constructor}}
1399 co_return;
1403 } // namespace CoroHandleMemberFunctionTest
1405 class awaitable_no_unused_warn {
1406 public:
1407 using handle_type = std::coroutine_handle<>;
1408 constexpr bool await_ready() noexcept { return false; }
1409 void await_suspend(handle_type) noexcept {}
1410 int await_resume() noexcept { return 1; }
1414 class awaitable_unused_warn {
1415 public:
1416 using handle_type = std::coroutine_handle<>;
1417 constexpr bool await_ready() noexcept { return false; }
1418 void await_suspend(handle_type) noexcept {}
1419 [[nodiscard]] int await_resume() noexcept { return 1; }
1422 template <class Await>
1423 struct check_warning_promise {
1424 coro<check_warning_promise> get_return_object();
1425 Await initial_suspend();
1426 Await final_suspend() noexcept;
1427 Await yield_value(int);
1428 void return_void();
1429 void unhandled_exception();
1433 coro<check_warning_promise<awaitable_no_unused_warn>>
1434 test_no_unused_warning() {
1435 co_await awaitable_no_unused_warn();
1436 co_yield 42;
1439 coro<check_warning_promise<awaitable_unused_warn>>
1440 test_unused_warning() {
1441 co_await awaitable_unused_warn(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
1442 co_yield 42; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
1445 struct missing_await_ready {
1446 void await_suspend(std::coroutine_handle<>);
1447 void await_resume();
1449 struct missing_await_suspend {
1450 bool await_ready();
1451 void await_resume();
1453 struct missing_await_resume {
1454 bool await_ready();
1455 void await_suspend(std::coroutine_handle<>);
1458 void test_missing_awaitable_members() {
1459 co_await missing_await_ready{}; // expected-error {{no member named 'await_ready' in 'missing_await_ready'}}
1460 co_await missing_await_suspend{}; // expected-error {{no member named 'await_suspend' in 'missing_await_suspend'}}
1461 co_await missing_await_resume{}; // expected-error {{no member named 'await_resume' in 'missing_await_resume'}}