165 lines · cpp
1// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 \2// RUN: -fsyntax-only -Wignored-qualifiers -Wno-error=return-type -verify \3// RUN: -fblocks4#include "Inputs/std-coroutine.h"5 6using namespace std;7 8template <class Begin>9struct Awaiter {10 bool await_ready();11 void await_suspend(coroutine_handle<>);12 Begin await_resume();13};14 15template <class Iter> struct BeginTag { BeginTag() = delete; };16template <class Iter> struct IncTag { IncTag() = delete; };17 18template <class Iter, bool Delete = false>19struct CoawaitTag { CoawaitTag() = delete; };20 21template <class T>22struct Iter {23 using value_type = T;24 using reference = T &;25 using pointer = T *;26 27 IncTag<Iter> operator++();28 reference operator*();29 pointer operator->();30};31template <class T> bool operator==(Iter<T>, Iter<T>);32template <class T> bool operator!=(Iter<T>, Iter<T>);33 34template <class T>35struct Range {36 BeginTag<Iter<T>> begin();37 Iter<T> end();38};39 40struct MyForLoopArrayAwaiter {41 struct promise_type {42 MyForLoopArrayAwaiter get_return_object() { return {}; }43 void return_void();44 void unhandled_exception();45 suspend_never initial_suspend();46 suspend_never final_suspend() noexcept;47 template <class T>48 Awaiter<T *> await_transform(T *) = delete; // expected-note {{explicitly deleted}}49 };50};51MyForLoopArrayAwaiter g() {52 int arr[10] = {0};53 for co_await(auto i : arr) {} // expected-warning {{'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated}}54 // expected-error@-1 {{call to deleted member function 'await_transform'}}55 // expected-note@-2 {{'await_transform' implicitly required by 'co_await' here}}56}57 58struct ForLoopAwaiterBadBeginTransform {59 struct promise_type {60 ForLoopAwaiterBadBeginTransform get_return_object();61 void return_void();62 void unhandled_exception();63 suspend_never initial_suspend();64 suspend_never final_suspend() noexcept;65 66 template <class T>67 Awaiter<T> await_transform(BeginTag<T>) = delete; // expected-note 1+ {{explicitly deleted}}68 69 template <class T>70 CoawaitTag<T> await_transform(IncTag<T>); // expected-note 1+ {{candidate}}71 };72};73ForLoopAwaiterBadBeginTransform bad_begin() {74 Range<int> R;75 for co_await(auto i : R) {} // expected-warning {{'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated}}76 // expected-error@-1 {{call to deleted member function 'await_transform'}}77 // expected-note@-2 {{'await_transform' implicitly required by 'co_await' here}}78}79template <class Dummy>80ForLoopAwaiterBadBeginTransform bad_begin_template(Dummy) {81 Range<Dummy> R;82 for co_await(auto i : R) {} // expected-warning {{'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated}}83 // expected-error@-1 {{call to deleted member function 'await_transform'}}84 // expected-note@-2 {{'await_transform' implicitly required by 'co_await' here}}85}86template ForLoopAwaiterBadBeginTransform bad_begin_template(int); // expected-note {{requested here}}87 88template <class Iter>89Awaiter<Iter> operator co_await(CoawaitTag<Iter, true>) = delete;90// expected-note@-1 1+ {{explicitly deleted}}91 92struct ForLoopAwaiterBadIncTransform {93 struct promise_type {94 ForLoopAwaiterBadIncTransform get_return_object();95 void return_void();96 void unhandled_exception();97 suspend_never initial_suspend();98 suspend_never final_suspend() noexcept;99 100 template <class T>101 Awaiter<T> await_transform(BeginTag<T> e);102 103 template <class T>104 CoawaitTag<T, true> await_transform(IncTag<T>);105 };106};107ForLoopAwaiterBadIncTransform bad_inc_transform() {108 Range<float> R;109 for co_await(auto i : R) {} // expected-warning {{'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated}}110 // expected-error@-1 {{overload resolution selected deleted operator 'co_await'}}111 // expected-note@-2 {{in implicit call to 'operator++' for iterator of type 'Range<float>'}}112}113 114template <class Dummy>115ForLoopAwaiterBadIncTransform bad_inc_transform_template(Dummy) {116 Range<Dummy> R;117 for co_await(auto i : R) {} // expected-warning {{'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated}}118 // expected-error@-1 {{overload resolution selected deleted operator 'co_await'}}119 // expected-note@-2 {{in implicit call to 'operator++' for iterator of type 'Range<long>'}}120}121template ForLoopAwaiterBadIncTransform bad_inc_transform_template(long); // expected-note {{requested here}}122 123// Ensure we mark and check the function as a coroutine even if it's124// never instantiated.125template <class T>126constexpr void never_instant(T) {127 static_assert(sizeof(T) != sizeof(T), "function should not be instantiated");128 for co_await(auto i : foo(T{})) {} // expected-warning {{'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated}}129 // expected-error@-1 {{'co_await' cannot be used in a constexpr function}}130}131 132namespace NS {133struct ForLoopAwaiterCoawaitLookup {134 struct promise_type {135 ForLoopAwaiterCoawaitLookup get_return_object();136 void return_void();137 void unhandled_exception();138 suspend_never initial_suspend();139 suspend_never final_suspend() noexcept;140 template <class T>141 CoawaitTag<T, false> await_transform(BeginTag<T> e);142 template <class T>143 Awaiter<T> await_transform(IncTag<T>);144 };145};146} // namespace NS147using NS::ForLoopAwaiterCoawaitLookup;148 149template <class T>150ForLoopAwaiterCoawaitLookup test_coawait_lookup(T) {151 Range<T> R;152 for co_await(auto i : R) {} // expected-warning {{'for co_await' belongs to CoroutineTS instead of C++20, which is deprecated}}153 // expected-error@-1 {{no member named 'await_ready' in 'CoawaitTag<Iter<int>>'}}154}155template ForLoopAwaiterCoawaitLookup test_coawait_lookup(int); // expected-note {{requested here}}156 157// FIXME: This test should fail as well since the newly declared operator co_await158// should not be found by lookup.159namespace NS2 {160template <class Iter>161Awaiter<Iter> operator co_await(CoawaitTag<Iter, false>);162}163using NS2::operator co_await;164template ForLoopAwaiterCoawaitLookup test_coawait_lookup(long);165