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>}}
29 template <class... Args
>
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
{};
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
;
55 bool await_ready() noexcept
;
57 void await_suspend(F
) noexcept
;
58 void await_resume() noexcept
;
61 struct suspend_always
{
62 bool await_ready() noexcept
{ return false; }
64 void await_suspend(F
) noexcept
;
65 void await_resume() noexcept
{}
68 struct suspend_never
{
69 bool await_ready() noexcept
{ return true; }
71 void await_suspend(F
) noexcept
;
72 void await_resume() noexcept
{}
75 struct auto_await_suspend
{
77 template <typename F
> auto await_suspend(F
) {}
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'}}
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'}}
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'}}
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}}
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}}
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}}
125 struct yielded_thing
{ const char *p
; short a
, b
; };
127 struct not_awaitable
{};
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
;
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}}
154 template <class PromiseType
= void>
155 struct coroutine_handle
{
156 static coroutine_handle
from_address(void *) noexcept
;
159 struct coroutine_handle
<void> {
160 template <class PromiseType
>
161 coroutine_handle(coroutine_handle
<PromiseType
>) noexcept
;
162 static coroutine_handle
from_address(void *) noexcept
;
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}}
172 co_yield
"foo"; // expected-error {{no matching}}
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
) {
186 co_return
{4}; // expected-warning {{braces around scalar initializer}}
188 co_return
"foo"; // expected-error {{cannot initialize a parameter of type 'int' with an lvalue of type 'const char[4]'}}
193 void co_await_non_dependent_arg(T
) {
196 template void co_await_non_dependent_arg(int);
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}}
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}}
217 void mixed_yield_template2(T
) {
219 // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}}
220 return; // expected-error {{return statement not allowed in coroutine}}
224 void mixed_yield_template3(T 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}}
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}}
242 void mixed_await_template(T
) {
244 // expected-note@-1 {{function is a coroutine due to use of 'co_await'}}
245 return; // expected-error {{not allowed in coroutine}}
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
) {
260 void mixed_coreturn(void_tag
, bool b
) {
262 co_return
; // expected-note {{use of 'co_return'}}
264 return; // expected-error {{not allowed in coroutine}}
267 void mixed_coreturn_invalid(bool b
) {
269 co_return
; // expected-note {{use of 'co_return'}}
270 // expected-error@-1 {{no member named 'return_void' in 'promise'}}
272 return; // expected-error {{not allowed in coroutine}}
276 void mixed_coreturn_template(void_tag
, bool b
, T v
) {
278 co_return v
; // expected-note {{use of 'co_return'}}
279 // expected-error@-1 {{no member named 'return_value' in 'promise_void'}}
281 return; // expected-error {{not allowed in coroutine}}
283 template void mixed_coreturn_template(void_tag
, bool, int); // expected-note {{requested here}}
286 void mixed_coreturn_template2(bool b
, T
) {
288 co_return v
; // expected-note {{use of 'co_return'}}
289 // expected-error@-1 {{use of undeclared identifier 'v'}}
291 return; // expected-error {{not allowed in coroutine}}
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}}
303 co_return
0; // expected-error {{'co_return' cannot be used in a destructor}}
305 void operator=(CtorDtor
&) {
308 void operator=(CtorDtor
const &) {
311 void operator=(CtorDtor
&&) {
314 void operator=(CtorDtor
const &&) {
317 void operator=(int) {
318 co_await a
; // OK. Not a special member
322 namespace std
{ class type_info
; }
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() {
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() {
358 } catch (...) { // FIXME: Emit a note diagnostic pointing out the try handler on this line.
360 co_await a
; // expected-error {{'co_await' cannot be used in the handler of a try block}}
361 []() -> void { co_await a
; }(); // OK
368 void await_in_lambda_in_catch_coroutine() {
371 []() -> void { co_await a
; }(); // OK
375 void yield_in_catch_coroutine() {
378 co_yield
1; // expected-error {{'co_yield' cannot be used in the handler of a try block}}
382 void return_in_catch_coroutine() {
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}}
403 struct await_arg_1
{};
404 struct await_arg_2
{};
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
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();
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();
455 awaitable
operator co_await(await_arg_1
);
457 template <typename T
, typename U
>
458 coro
<T
> await_template_3(U 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'}}}
470 coro
<T
> dep_mem_fn(U t
) {
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}}
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
);
510 coro
<transform_promise
> dependent_member
<long>::dep_mem_fn
<transform_promise
>(long) {
511 co_await transform_awaitable
{};
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
{};
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}}
545 co_await f
; // expected-error {{reference to overloaded function}}
548 co_yield g
; // expected-error {{no matching member function for call to 'yield_value'}}
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
) {
561 void z(yield_fn_tag
) {
567 struct bad_promise_1
{
568 suspend_always
initial_suspend();
569 suspend_always
final_suspend() noexcept
;
570 void unhandled_exception();
573 coro
<bad_promise_1
> missing_get_return_object() { // expected-error {{no member named 'get_return_object' in 'bad_promise_1'}}
577 struct bad_promise_2
{
578 coro
<bad_promise_2
> get_return_object();
579 suspend_always
final_suspend() noexcept
;
580 void unhandled_exception();
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'}}
588 struct bad_promise_3
{
589 coro
<bad_promise_3
> get_return_object();
590 suspend_always
initial_suspend();
591 void unhandled_exception();
594 coro
<bad_promise_3
> missing_final_suspend() noexcept
{ // expected-error {{no member named 'final_suspend' in 'bad_promise_3'}}
598 struct bad_promise_4
{
599 coro
<bad_promise_4
> get_return_object();
600 not_awaitable
initial_suspend();
601 suspend_always
final_suspend() noexcept
;
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
;
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'}}
636 coro
<T
> bad_implicit_return_dependent(T
) { // expected-error {{'bad_promise_6' declares both 'return_value' and 'return_void'}}
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
;
647 coro
<bad_promise_7
> no_unhandled_exception() { // expected-error {{'bad_promise_7' is required to declare the member 'unhandled_exception()'}}
652 coro
<T
> no_unhandled_exception_dependent(T
) { // expected-error {{'bad_promise_7' is required to declare the member 'unhandled_exception()'}}
655 template coro
<bad_promise_7
> no_unhandled_exception_dependent(bad_promise_7
); // expected-note {{in instantiation}}
657 struct bad_promise_base
{
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}}
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}}
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}}
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
;
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
; }
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
730 template<typename T
> void ok_generic_lambda_coawait_PR41909() {
731 [](auto& arg
) -> coro
<good_promise_1
> { // expected-warning {{expression result unused}}
734 [](auto &arg
) -> coro
<good_promise_1
> {
737 [](auto &arg
) ->coro
<good_promise_1
> { // expected-warning {{expression result unused}}
738 []() -> coro
<good_promise_1
> {
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
;
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}}
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
{};
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();
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.
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();
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}}
837 coro
<T
> dependent_throwing_in_class_new(T
) { // expected-note {{call to 'operator new' implicitly required by coroutine function here}}
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();
849 static coro
<good_promise_13
> get_return_object_on_allocation_failure();
851 coro
<good_promise_13
> uses_nothrow_new() {
856 coro
<T
> dependent_uses_nothrow_new(T
) {
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
;
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) {
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
;
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
;
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) {
901 struct mismatch_gro_type_tag1
{};
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
{};
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
{};
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
{};
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]). —
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() {
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
{
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'}}
1012 bool await_suspend(std::coroutine_handle
<>);
1013 void await_resume();
1015 struct await_ready_explicit_bool
{
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
{
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
;
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}}
1059 template <int ID
= 0>
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>'}}
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;
1079 constexpr bool IsSameV
<T
, T
> = true;
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
...>>;
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);
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
{
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'}}
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'}}
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'}}
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
;
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')}}
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
;
1341 void unhandled_exception();
1344 coro
<good_promise_default_constructor
>
1345 good_coroutine_calls_default_constructor() {
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
;
1359 void unhandled_exception();
1362 coro
<good_promise_custom_constructor
>
1363 good_coroutine_calls_custom_constructor(double, float, int) {
1368 coro
<good_promise_custom_constructor
>
1369 good_coroutine_calls_custom_constructor(float, int) {
1372 coro
<good_promise_custom_constructor
>
1373 static good_coroutine_calls_custom_constructor(double, float, int) {
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
;
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')}}
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}}
1403 } // namespace CoroHandleMemberFunctionTest
1405 class awaitable_no_unused_warn
{
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
{
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);
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();
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
{
1451 void await_resume();
1453 struct missing_await_resume
{
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'}}