Clang Project

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