brintos

brintos / llvm-project-archived public Read only

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