blob: e82cb62f12d42b0cada011bcd3f2d29afcde5020 [file] [log] [blame]
Richard Smithcfd53b42015-10-22 06:13:50 +00001// RUN: %clang_cc1 -std=c++14 -fcoroutines -verify %s
2
Richard Smith9f690bd2015-10-27 06:02:45 +00003struct awaitable {
4 bool await_ready();
5 void await_suspend(); // FIXME: coroutine_handle
6 void await_resume();
7} a;
8
Richard Smith2af65c42015-11-24 02:34:39 +00009struct suspend_always {
10 bool await_ready() { return false; }
11 void await_suspend() {}
12 void await_resume() {}
13};
14
15struct suspend_never {
16 bool await_ready() { return true; }
17 void await_suspend() {}
18 void await_resume() {}
19};
20
Richard Smith9f690bd2015-10-27 06:02:45 +000021void no_coroutine_traits() {
22 co_await a; // expected-error {{need to include <coroutine>}}
23}
24
25namespace std {
26 template<typename ...T> struct coroutine_traits; // expected-note {{declared here}}
27};
28
Richard Smith2af65c42015-11-24 02:34:39 +000029template<typename Promise> struct coro {};
30template<typename Promise, typename... Ps>
31struct std::coroutine_traits<coro<Promise>, Ps...> {
32 using promise_type = Promise;
33};
34
Richard Smith9f690bd2015-10-27 06:02:45 +000035void no_specialization() {
36 co_await a; // expected-error {{implicit instantiation of undefined template 'std::coroutine_traits<void>'}}
37}
38
39template<typename ...T> struct std::coroutine_traits<int, T...> {};
40
41int no_promise_type() {
Richard Smith9b2f53e2015-11-19 02:36:35 +000042 co_await a; // expected-error {{this function cannot be a coroutine: 'std::coroutine_traits<int>' has no member named 'promise_type'}}
43}
44
45template<> struct std::coroutine_traits<double, double> { typedef int promise_type; };
46double bad_promise_type(double) {
47 co_await a; // expected-error {{this function cannot be a coroutine: 'std::coroutine_traits<double, double>::promise_type' (aka 'int') is not a class}}
Richard Smith9f690bd2015-10-27 06:02:45 +000048}
49
Richard Smith23da82c2015-11-20 22:40:06 +000050template<> struct std::coroutine_traits<double, int> {
51 struct promise_type {};
52};
53double bad_promise_type_2(int) {
54 co_yield 0; // expected-error {{no member named 'yield_value' in 'std::coroutine_traits<double, int>::promise_type'}}
55}
56
Richard Smith2af65c42015-11-24 02:34:39 +000057struct promise; // expected-note 2{{forward declaration}}
Richard Smith9f690bd2015-10-27 06:02:45 +000058template<typename ...T> struct std::coroutine_traits<void, T...> { using promise_type = promise; };
59
60 // FIXME: This diagnostic is terrible.
61void undefined_promise() { // expected-error {{variable has incomplete type 'promise_type'}}
Richard Smith2af65c42015-11-24 02:34:39 +000062 // FIXME: This diagnostic doesn't make any sense.
63 // expected-error@-2 {{incomplete definition of type 'promise'}}
Richard Smith9f690bd2015-10-27 06:02:45 +000064 co_await a;
65}
66
Richard Smithae3d1472015-11-20 22:47:10 +000067struct yielded_thing { const char *p; short a, b; };
Richard Smith23da82c2015-11-20 22:40:06 +000068
Richard Smithd7bed4d2015-11-22 02:57:17 +000069struct not_awaitable {};
70
Richard Smith23da82c2015-11-20 22:40:06 +000071struct promise {
Richard Smith2af65c42015-11-24 02:34:39 +000072 void get_return_object();
73 suspend_always initial_suspend();
74 suspend_always final_suspend();
Richard Smith71d403e2015-11-22 07:33:28 +000075 awaitable yield_value(int); // expected-note 2{{candidate}}
76 awaitable yield_value(yielded_thing); // expected-note 2{{candidate}}
77 not_awaitable yield_value(void()); // expected-note 2{{candidate}}
Richard Smith4ba66602015-11-22 07:05:16 +000078 void return_void();
Richard Smith71d403e2015-11-22 07:33:28 +000079 void return_value(int); // expected-note 2{{here}}
Richard Smith23da82c2015-11-20 22:40:06 +000080};
81
82void yield() {
83 co_yield 0;
Richard Smithae3d1472015-11-20 22:47:10 +000084 co_yield {"foo", 1, 2};
85 co_yield {1e100}; // expected-error {{cannot be narrowed}} expected-note {{explicit cast}} expected-warning {{changes value}} expected-warning {{braces around scalar}}
86 co_yield {"foo", __LONG_LONG_MAX__}; // expected-error {{cannot be narrowed}} expected-note {{explicit cast}} expected-warning {{changes value}}
87 co_yield {"foo"};
Richard Smith23da82c2015-11-20 22:40:06 +000088 co_yield "foo"; // expected-error {{no matching}}
Richard Smithd7bed4d2015-11-22 02:57:17 +000089 co_yield 1.0;
90 co_yield yield; // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
Richard Smith23da82c2015-11-20 22:40:06 +000091}
Richard Smith9f690bd2015-10-27 06:02:45 +000092
Richard Smith4ba66602015-11-22 07:05:16 +000093void coreturn(int n) {
94 co_await a;
95 if (n == 0)
96 co_return 3;
97 if (n == 1)
98 co_return {4};
99 if (n == 2)
100 co_return "foo"; // expected-error {{cannot initialize a parameter of type 'int' with an lvalue of type 'const char [4]'}}
101 co_return;
102}
103
Richard Smithcfd53b42015-10-22 06:13:50 +0000104void mixed_yield() {
Richard Smith9f690bd2015-10-27 06:02:45 +0000105 co_yield 0; // expected-note {{use of 'co_yield'}}
106 return; // expected-error {{not allowed in coroutine}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000107}
108
109void mixed_await() {
Richard Smith9f690bd2015-10-27 06:02:45 +0000110 co_await a; // expected-note {{use of 'co_await'}}
111 return; // expected-error {{not allowed in coroutine}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000112}
113
114void only_coreturn() {
Richard Smith9f690bd2015-10-27 06:02:45 +0000115 co_return; // expected-warning {{'co_return' used in a function that uses neither 'co_await' nor 'co_yield'}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000116}
117
118void mixed_coreturn(bool b) {
Richard Smithcfd53b42015-10-22 06:13:50 +0000119 if (b)
Richard Smith9f690bd2015-10-27 06:02:45 +0000120 // expected-warning@+1 {{'co_return' used in a function that uses neither}}
121 co_return; // expected-note {{use of 'co_return'}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000122 else
Richard Smith9f690bd2015-10-27 06:02:45 +0000123 return; // expected-error {{not allowed in coroutine}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000124}
125
126struct CtorDtor {
127 CtorDtor() {
128 co_yield 0; // expected-error {{'co_yield' cannot be used in a constructor}}
129 }
Richard Smith9f690bd2015-10-27 06:02:45 +0000130 CtorDtor(awaitable a) {
Richard Smithcfd53b42015-10-22 06:13:50 +0000131 // The spec doesn't say this is ill-formed, but it must be.
Richard Smith9f690bd2015-10-27 06:02:45 +0000132 co_await a; // expected-error {{'co_await' cannot be used in a constructor}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000133 }
134 ~CtorDtor() {
135 co_return 0; // expected-error {{'co_return' cannot be used in a destructor}}
136 }
137 // FIXME: The spec says this is ill-formed.
138 void operator=(CtorDtor&) {
139 co_yield 0;
140 }
141};
142
Richard Smith744b2242015-11-20 02:54:01 +0000143void unevaluated() {
144 decltype(co_await a); // expected-error {{cannot be used in an unevaluated context}}
145 sizeof(co_await a); // expected-error {{cannot be used in an unevaluated context}}
146 typeid(co_await a); // expected-error {{cannot be used in an unevaluated context}}
147 decltype(co_yield a); // expected-error {{cannot be used in an unevaluated context}}
148 sizeof(co_yield a); // expected-error {{cannot be used in an unevaluated context}}
149 typeid(co_yield a); // expected-error {{cannot be used in an unevaluated context}}
150}
151
152constexpr void constexpr_coroutine() {
153 co_yield 0; // expected-error {{'co_yield' cannot be used in a constexpr function}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000154}
155
156void varargs_coroutine(const char *, ...) {
Richard Smith9f690bd2015-10-27 06:02:45 +0000157 co_await a; // expected-error {{'co_await' cannot be used in a varargs function}}
158}
159
160struct outer {};
161
162namespace dependent_operator_co_await_lookup {
163 template<typename T> void await_template(T t) {
164 // no unqualified lookup results
165 co_await t; // expected-error {{no member named 'await_ready' in 'dependent_operator_co_await_lookup::not_awaitable'}}
166 // expected-error@-1 {{call to function 'operator co_await' that is neither visible in the template definition nor found by argument-dependent lookup}}
167 };
168 template void await_template(awaitable);
169
170 struct indirectly_awaitable { indirectly_awaitable(outer); };
171 awaitable operator co_await(indirectly_awaitable); // expected-note {{should be declared prior to}}
172 template void await_template(indirectly_awaitable);
173
174 struct not_awaitable {};
175 template void await_template(not_awaitable); // expected-note {{instantiation}}
176
177 template<typename T> void await_template_2(T t) {
178 // one unqualified lookup result
179 co_await t;
180 };
181 template void await_template(outer); // expected-note {{instantiation}}
182 template void await_template_2(outer);
Richard Smithcfd53b42015-10-22 06:13:50 +0000183}
Richard Smith10610f72015-11-20 22:57:24 +0000184
Richard Smith71d403e2015-11-22 07:33:28 +0000185struct yield_fn_tag {};
186template<> struct std::coroutine_traits<void, yield_fn_tag> {
187 struct promise_type {
188 // FIXME: add an await_transform overload for functions
189 awaitable yield_value(int());
190 void return_value(int());
Richard Smith2af65c42015-11-24 02:34:39 +0000191
192 suspend_never initial_suspend();
193 suspend_never final_suspend();
194 void get_return_object();
Richard Smith71d403e2015-11-22 07:33:28 +0000195 };
196};
197
Richard Smith10610f72015-11-20 22:57:24 +0000198namespace placeholder {
Richard Smith71d403e2015-11-22 07:33:28 +0000199 awaitable f(), f(int); // expected-note 4{{possible target}}
200 int g(), g(int); // expected-note 2{{candidate}}
Richard Smith10610f72015-11-20 22:57:24 +0000201 void x() {
202 co_await f; // expected-error {{reference to overloaded function}}
203 }
204 void y() {
Richard Smith71d403e2015-11-22 07:33:28 +0000205 co_yield g; // expected-error {{no matching member function for call to 'yield_value'}}
Richard Smith10610f72015-11-20 22:57:24 +0000206 }
207 void z() {
208 co_await a;
Richard Smith71d403e2015-11-22 07:33:28 +0000209 co_return g; // expected-error {{address of overloaded function 'g' does not match required type 'int'}}
210 }
211
212 void x(yield_fn_tag) {
213 co_await f; // expected-error {{reference to overloaded function}}
214 }
215 void y(yield_fn_tag) {
216 co_yield g;
217 }
218 void z(yield_fn_tag) {
219 co_await a;
220 co_return g;
Richard Smith10610f72015-11-20 22:57:24 +0000221 }
222}
Richard Smith2af65c42015-11-24 02:34:39 +0000223
224struct bad_promise_1 {
225 suspend_always initial_suspend();
226 suspend_always final_suspend();
227};
228coro<bad_promise_1> missing_get_return_object() { // expected-error {{no member named 'get_return_object' in 'bad_promise_1'}}
229 co_await a;
230}
231
232struct bad_promise_2 {
233 coro<bad_promise_2> get_return_object();
234 // FIXME: We shouldn't offer a typo-correction here!
235 suspend_always final_suspend(); // expected-note {{here}}
236};
237coro<bad_promise_2> missing_initial_suspend() { // expected-error {{no member named 'initial_suspend' in 'bad_promise_2'}}
238 co_await a;
239}
240
241struct bad_promise_3 {
242 coro<bad_promise_3> get_return_object();
243 // FIXME: We shouldn't offer a typo-correction here!
244 suspend_always initial_suspend(); // expected-note {{here}}
245};
246coro<bad_promise_3> missing_final_suspend() { // expected-error {{no member named 'final_suspend' in 'bad_promise_3'}}
247 co_await a;
248}
249
250struct bad_promise_4 {
251 coro<bad_promise_4> get_return_object();
252 not_awaitable initial_suspend();
253 suspend_always final_suspend();
254};
255// FIXME: This diagnostic is terrible.
256coro<bad_promise_4> bad_initial_suspend() { // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
257 co_await a;
258}
259
260struct bad_promise_5 {
261 coro<bad_promise_5> get_return_object();
262 suspend_always initial_suspend();
263 not_awaitable final_suspend();
264};
265// FIXME: This diagnostic is terrible.
266coro<bad_promise_5> bad_final_suspend() { // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
267 co_await a;
268}