1 // RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 \
2 // RUN: -fsyntax-only -Wignored-qualifiers -Wno-error=return-type -verify \
4 #include "Inputs/std-coroutine.h"
11 void await_suspend(coroutine_handle
<>);
15 template <class Iter
> struct BeginTag
{ BeginTag() = delete; };
16 template <class Iter
> struct IncTag
{ IncTag() = delete; };
18 template <class Iter
, bool Delete
= false>
19 struct CoawaitTag
{ CoawaitTag() = delete; };
24 using reference
= T
&;
27 IncTag
<Iter
> operator++();
28 reference
operator*();
31 template <class T
> bool operator==(Iter
<T
>, Iter
<T
>);
32 template <class T
> bool operator!=(Iter
<T
>, Iter
<T
>);
36 BeginTag
<Iter
<T
>> begin();
40 struct MyForLoopArrayAwaiter
{
42 MyForLoopArrayAwaiter
get_return_object() { return {}; }
44 void unhandled_exception();
45 suspend_never
initial_suspend();
46 suspend_never
final_suspend() noexcept
;
48 Awaiter
<T
*> await_transform(T
*) = delete; // expected-note {{explicitly deleted}}
51 MyForLoopArrayAwaiter
g() {
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}}
58 struct ForLoopAwaiterBadBeginTransform
{
60 ForLoopAwaiterBadBeginTransform
get_return_object();
62 void unhandled_exception();
63 suspend_never
initial_suspend();
64 suspend_never
final_suspend() noexcept
;
67 Awaiter
<T
> await_transform(BeginTag
<T
>) = delete; // expected-note 1+ {{explicitly deleted}}
70 CoawaitTag
<T
> await_transform(IncTag
<T
>); // expected-note 1+ {{candidate}}
73 ForLoopAwaiterBadBeginTransform
bad_begin() {
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}}
79 template <class Dummy
>
80 ForLoopAwaiterBadBeginTransform
bad_begin_template(Dummy
) {
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}}
86 template ForLoopAwaiterBadBeginTransform
bad_begin_template(int); // expected-note {{requested here}}
89 Awaiter
<Iter
> operator co_await(CoawaitTag
<Iter
, true>) = delete;
90 // expected-note@-1 1+ {{explicitly deleted}}
92 struct ForLoopAwaiterBadIncTransform
{
94 ForLoopAwaiterBadIncTransform
get_return_object();
96 void unhandled_exception();
97 suspend_never
initial_suspend();
98 suspend_never
final_suspend() noexcept
;
101 Awaiter
<T
> await_transform(BeginTag
<T
> e
);
104 CoawaitTag
<T
, true> await_transform(IncTag
<T
>);
107 ForLoopAwaiterBadIncTransform
bad_inc_transform() {
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>'}}
114 template <class Dummy
>
115 ForLoopAwaiterBadIncTransform
bad_inc_transform_template(Dummy
) {
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>'}}
121 template ForLoopAwaiterBadIncTransform
bad_inc_transform_template(long); // expected-note {{requested here}}
123 // Ensure we mark and check the function as a coroutine even if it's
124 // never instantiated.
126 constexpr 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}}
133 struct ForLoopAwaiterCoawaitLookup
{
134 struct promise_type
{
135 ForLoopAwaiterCoawaitLookup
get_return_object();
137 void unhandled_exception();
138 suspend_never
initial_suspend();
139 suspend_never
final_suspend() noexcept
;
141 CoawaitTag
<T
, false> await_transform(BeginTag
<T
> e
);
143 Awaiter
<T
> await_transform(IncTag
<T
>);
147 using NS::ForLoopAwaiterCoawaitLookup
;
150 ForLoopAwaiterCoawaitLookup
test_coawait_lookup(T
) {
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>, false>'}}
155 template ForLoopAwaiterCoawaitLookup
test_coawait_lookup(int); // expected-note {{requested here}}
157 // FIXME: This test should fail as well since the newly declared operator co_await
158 // should not be found by lookup.
160 template <class Iter
>
161 Awaiter
<Iter
> operator co_await(CoawaitTag
<Iter
, false>);
163 using NS2::operator co_await
;
164 template ForLoopAwaiterCoawaitLookup
test_coawait_lookup(long);