blob: a75c2d62f9110537107545717950f4d7e36be35e [file] [log] [blame]
Eric Fiseliera9fdb342017-03-23 00:33:33 +00001// RUN: %clang_cc1 -std=c++14 -fcoroutines-ts -verify %s -fcxx-exceptions -fexceptions
Richard Smithcfd53b42015-10-22 06:13:50 +00002
Eric Fiseliera5465282016-09-29 21:47:39 +00003void no_coroutine_traits_bad_arg_await() {
Gor Nishanov3e048bb2016-10-04 00:31:16 +00004 co_await a; // expected-error {{include <experimental/coroutine>}}
Eric Fiseliera5465282016-09-29 21:47:39 +00005 // expected-error@-1 {{use of undeclared identifier 'a'}}
6}
7
8void no_coroutine_traits_bad_arg_yield() {
Gor Nishanov3e048bb2016-10-04 00:31:16 +00009 co_yield a; // expected-error {{include <experimental/coroutine>}}
Eric Fiseliera5465282016-09-29 21:47:39 +000010 // expected-error@-1 {{use of undeclared identifier 'a'}}
11}
12
13
14void no_coroutine_traits_bad_arg_return() {
Gor Nishanov3e048bb2016-10-04 00:31:16 +000015 co_return a; // expected-error {{include <experimental/coroutine>}}
Eric Fiseliera5465282016-09-29 21:47:39 +000016 // expected-error@-1 {{use of undeclared identifier 'a'}}
17}
18
Richard Smith9f690bd2015-10-27 06:02:45 +000019void no_coroutine_traits() {
Gor Nishanov6dcb0eb2017-03-09 03:09:43 +000020 co_await 4; // expected-error {{std::experimental::coroutine_traits type was not found; include <experimental/coroutine>}}
Richard Smith9f690bd2015-10-27 06:02:45 +000021}
22
23namespace std {
Gor Nishanov3e048bb2016-10-04 00:31:16 +000024namespace experimental {
25template <typename... T>
26struct coroutine_traits; // expected-note {{declared here}}
Gor Nishanov6dcb0eb2017-03-09 03:09:43 +000027}} // namespace std::experimental
Richard Smith9f690bd2015-10-27 06:02:45 +000028
Richard Smith2af65c42015-11-24 02:34:39 +000029template<typename Promise> struct coro {};
Gor Nishanov3e048bb2016-10-04 00:31:16 +000030template <typename Promise, typename... Ps>
31struct std::experimental::coroutine_traits<coro<Promise>, Ps...> {
Richard Smith2af65c42015-11-24 02:34:39 +000032 using promise_type = Promise;
33};
34
Gor Nishanov6dcb0eb2017-03-09 03:09:43 +000035struct awaitable {
36 bool await_ready();
37 template <typename F> void await_suspend(F);
38 void await_resume();
39} a;
40
41struct suspend_always {
42 bool await_ready() { return false; }
43 template <typename F> void await_suspend(F);
44 void await_resume() {}
45};
46
47struct suspend_never {
48 bool await_ready() { return true; }
49 template <typename F> void await_suspend(F);
50 void await_resume() {}
51};
52
Richard Smith9f690bd2015-10-27 06:02:45 +000053void no_specialization() {
Gor Nishanov3e048bb2016-10-04 00:31:16 +000054 co_await a; // expected-error {{implicit instantiation of undefined template 'std::experimental::coroutine_traits<void>'}}
Richard Smith9f690bd2015-10-27 06:02:45 +000055}
56
Gor Nishanov3e048bb2016-10-04 00:31:16 +000057template <typename... T>
58struct std::experimental::coroutine_traits<int, T...> {};
Richard Smith9f690bd2015-10-27 06:02:45 +000059
Eric Fiselier89bf0e72017-03-06 22:52:28 +000060int no_promise_type() { // expected-error {{this function cannot be a coroutine: 'std::experimental::coroutine_traits<int>' has no member named 'promise_type'}}
61 co_await a;
Richard Smith9b2f53e2015-11-19 02:36:35 +000062}
63
Gor Nishanov3e048bb2016-10-04 00:31:16 +000064template <>
65struct std::experimental::coroutine_traits<double, double> { typedef int promise_type; };
Eric Fiselier89bf0e72017-03-06 22:52:28 +000066double 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}}
67 co_await a;
Richard Smith9f690bd2015-10-27 06:02:45 +000068}
69
Gor Nishanov3e048bb2016-10-04 00:31:16 +000070template <>
71struct std::experimental::coroutine_traits<double, int> {
Richard Smith23da82c2015-11-20 22:40:06 +000072 struct promise_type {};
73};
Eric Fiselier20f25cb2017-03-06 23:38:15 +000074double bad_promise_type_2(int) { // expected-error {{no member named 'initial_suspend'}}
Gor Nishanov3e048bb2016-10-04 00:31:16 +000075 co_yield 0; // expected-error {{no member named 'yield_value' in 'std::experimental::coroutine_traits<double, int>::promise_type'}}
Richard Smith23da82c2015-11-20 22:40:06 +000076}
77
Eric Fiselier89bf0e72017-03-06 22:52:28 +000078struct promise; // expected-note {{forward declaration}}
Eric Fiselier98131312016-10-06 21:23:38 +000079struct promise_void;
80struct void_tag {};
Gor Nishanov3e048bb2016-10-04 00:31:16 +000081template <typename... T>
82struct std::experimental::coroutine_traits<void, T...> { using promise_type = promise; };
Eric Fiselier98131312016-10-06 21:23:38 +000083template <typename... T>
84struct std::experimental::coroutine_traits<void, void_tag, T...>
85{ using promise_type = promise_void; };
Richard Smith9f690bd2015-10-27 06:02:45 +000086
Eric Fiselier20f25cb2017-03-06 23:38:15 +000087// FIXME: This diagnostic is terrible.
Eric Fiselier89bf0e72017-03-06 22:52:28 +000088void undefined_promise() { // expected-error {{this function cannot be a coroutine: 'experimental::coroutine_traits<void>::promise_type' (aka 'promise') is an incomplete type}}
Richard Smith9f690bd2015-10-27 06:02:45 +000089 co_await a;
90}
91
Richard Smithae3d1472015-11-20 22:47:10 +000092struct yielded_thing { const char *p; short a, b; };
Richard Smith23da82c2015-11-20 22:40:06 +000093
Richard Smithd7bed4d2015-11-22 02:57:17 +000094struct not_awaitable {};
95
Richard Smith23da82c2015-11-20 22:40:06 +000096struct promise {
Richard Smith2af65c42015-11-24 02:34:39 +000097 void get_return_object();
98 suspend_always initial_suspend();
99 suspend_always final_suspend();
Richard Smith71d403e2015-11-22 07:33:28 +0000100 awaitable yield_value(int); // expected-note 2{{candidate}}
101 awaitable yield_value(yielded_thing); // expected-note 2{{candidate}}
102 not_awaitable yield_value(void()); // expected-note 2{{candidate}}
Richard Smith71d403e2015-11-22 07:33:28 +0000103 void return_value(int); // expected-note 2{{here}}
Eric Fiseliera9fdb342017-03-23 00:33:33 +0000104 void unhandled_exception();
Richard Smith23da82c2015-11-20 22:40:06 +0000105};
106
Eric Fiselier98131312016-10-06 21:23:38 +0000107struct promise_void {
108 void get_return_object();
109 suspend_always initial_suspend();
110 suspend_always final_suspend();
Eric Fiselier98131312016-10-06 21:23:38 +0000111 void return_void();
Eric Fiseliera9fdb342017-03-23 00:33:33 +0000112 void unhandled_exception();
Eric Fiselier98131312016-10-06 21:23:38 +0000113};
114
Gor Nishanov6dcb0eb2017-03-09 03:09:43 +0000115void no_coroutine_handle() { // expected-error {{std::experimental::coroutine_handle type was not found; include <experimental/coroutine> before defining a coroutine}}
116 //expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
117 co_return 5; //expected-note {{function is a coroutine due to use of 'co_return' here}}
118}
119
120namespace std {
121namespace experimental {
122template <class PromiseType = void>
123struct coroutine_handle {
124 static coroutine_handle from_address(void *);
125};
126template <>
127struct coroutine_handle<void> {
128 template <class PromiseType>
129 coroutine_handle(coroutine_handle<PromiseType>);
130 static coroutine_handle from_address(void *);
131};
132}} // namespace std::experimental
133
Richard Smith23da82c2015-11-20 22:40:06 +0000134void yield() {
135 co_yield 0;
Richard Smithae3d1472015-11-20 22:47:10 +0000136 co_yield {"foo", 1, 2};
137 co_yield {1e100}; // expected-error {{cannot be narrowed}} expected-note {{explicit cast}} expected-warning {{changes value}} expected-warning {{braces around scalar}}
138 co_yield {"foo", __LONG_LONG_MAX__}; // expected-error {{cannot be narrowed}} expected-note {{explicit cast}} expected-warning {{changes value}}
139 co_yield {"foo"};
Richard Smith23da82c2015-11-20 22:40:06 +0000140 co_yield "foo"; // expected-error {{no matching}}
Richard Smithd7bed4d2015-11-22 02:57:17 +0000141 co_yield 1.0;
142 co_yield yield; // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
Richard Smith23da82c2015-11-20 22:40:06 +0000143}
Richard Smith9f690bd2015-10-27 06:02:45 +0000144
Richard Smith4ba66602015-11-22 07:05:16 +0000145void coreturn(int n) {
146 co_await a;
147 if (n == 0)
148 co_return 3;
149 if (n == 1)
Eric Fiselier98131312016-10-06 21:23:38 +0000150 co_return {4}; // expected-warning {{braces around scalar initializer}}
Richard Smith4ba66602015-11-22 07:05:16 +0000151 if (n == 2)
152 co_return "foo"; // expected-error {{cannot initialize a parameter of type 'int' with an lvalue of type 'const char [4]'}}
Eric Fiselier98131312016-10-06 21:23:38 +0000153 co_return 42;
Richard Smith4ba66602015-11-22 07:05:16 +0000154}
155
Eric Fiselier8d409e82017-03-09 05:01:31 +0000156template <class T>
157void co_await_non_dependent_arg(T) {
158 co_await a;
159}
160template void co_await_non_dependent_arg(int);
161
Richard Smithcfd53b42015-10-22 06:13:50 +0000162void mixed_yield() {
Richard Smith9f690bd2015-10-27 06:02:45 +0000163 co_yield 0; // expected-note {{use of 'co_yield'}}
164 return; // expected-error {{not allowed in coroutine}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000165}
166
Eric Fiseliercac0a592017-03-11 02:35:37 +0000167void mixed_yield_invalid() {
168 co_yield blah; // expected-error {{use of undeclared identifier}}
169 // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}}
170 return; // expected-error {{return statement not allowed in coroutine}}
171}
172
173template <class T>
174void mixed_yield_template(T) {
175 co_yield blah; // expected-error {{use of undeclared identifier}}
176 // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}}
177 return; // expected-error {{return statement not allowed in coroutine}}
178}
179
180template <class T>
181void mixed_yield_template2(T) {
182 co_yield 42;
183 // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}}
184 return; // expected-error {{return statement not allowed in coroutine}}
185}
186
187template <class T>
188void mixed_yield_template3(T v) {
189 co_yield blah(v);
190 // expected-note@-1 {{function is a coroutine due to use of 'co_yield'}}
191 return; // expected-error {{return statement not allowed in coroutine}}
192}
193
Richard Smithcfd53b42015-10-22 06:13:50 +0000194void mixed_await() {
Richard Smith9f690bd2015-10-27 06:02:45 +0000195 co_await a; // expected-note {{use of 'co_await'}}
196 return; // expected-error {{not allowed in coroutine}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000197}
198
Eric Fiseliercac0a592017-03-11 02:35:37 +0000199void mixed_await_invalid() {
200 co_await 42; // expected-error {{'int' is not a structure or union}}
201 // expected-note@-1 {{function is a coroutine due to use of 'co_await'}}
202 return; // expected-error {{not allowed in coroutine}}
203}
204
205template <class T>
206void mixed_await_template(T) {
207 co_await 42;
208 // expected-note@-1 {{function is a coroutine due to use of 'co_await'}}
209 return; // expected-error {{not allowed in coroutine}}
210}
211
212template <class T>
213void mixed_await_template2(T v) {
214 co_await v; // expected-error {{'long' is not a structure or union}}
215 // expected-note@-1 {{function is a coroutine due to use of 'co_await'}}
216 return; // expected-error {{not allowed in coroutine}}
217}
218template void mixed_await_template2(long); // expected-note {{requested here}}
219
Eric Fiselier98131312016-10-06 21:23:38 +0000220void only_coreturn(void_tag) {
Gor Nishanovd97f6bf2017-01-10 00:08:31 +0000221 co_return; // OK
Richard Smithcfd53b42015-10-22 06:13:50 +0000222}
223
Eric Fiselier98131312016-10-06 21:23:38 +0000224void mixed_coreturn(void_tag, bool b) {
Richard Smithcfd53b42015-10-22 06:13:50 +0000225 if (b)
Richard Smith9f690bd2015-10-27 06:02:45 +0000226 co_return; // expected-note {{use of 'co_return'}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000227 else
Richard Smith9f690bd2015-10-27 06:02:45 +0000228 return; // expected-error {{not allowed in coroutine}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000229}
230
Eric Fiseliercac0a592017-03-11 02:35:37 +0000231void mixed_coreturn_invalid(bool b) {
232 if (b)
233 co_return; // expected-note {{use of 'co_return'}}
234 // expected-error@-1 {{no member named 'return_void' in 'promise'}}
235 else
236 return; // expected-error {{not allowed in coroutine}}
237}
238
239template <class T>
240void mixed_coreturn_template(void_tag, bool b, T v) {
241 if (b)
242 co_return v; // expected-note {{use of 'co_return'}}
243 // expected-error@-1 {{no member named 'return_value' in 'promise_void'}}
244 else
245 return; // expected-error {{not allowed in coroutine}}
246}
247template void mixed_coreturn_template(void_tag, bool, int); // expected-note {{requested here}}
248
249template <class T>
250void mixed_coreturn_template2(bool b, T) {
251 if (b)
252 co_return v; // expected-note {{use of 'co_return'}}
253 // expected-error@-1 {{use of undeclared identifier 'v'}}
254 else
255 return; // expected-error {{not allowed in coroutine}}
256}
257
Richard Smithcfd53b42015-10-22 06:13:50 +0000258struct CtorDtor {
259 CtorDtor() {
260 co_yield 0; // expected-error {{'co_yield' cannot be used in a constructor}}
261 }
Richard Smith9f690bd2015-10-27 06:02:45 +0000262 CtorDtor(awaitable a) {
Richard Smithcfd53b42015-10-22 06:13:50 +0000263 // The spec doesn't say this is ill-formed, but it must be.
Richard Smith9f690bd2015-10-27 06:02:45 +0000264 co_await a; // expected-error {{'co_await' cannot be used in a constructor}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000265 }
266 ~CtorDtor() {
267 co_return 0; // expected-error {{'co_return' cannot be used in a destructor}}
268 }
269 // FIXME: The spec says this is ill-formed.
270 void operator=(CtorDtor&) {
Eric Fiselierc8efda72016-10-27 18:43:28 +0000271 co_yield 0; // expected-error {{'co_yield' cannot be used in a copy assignment operator}}
272 }
273 void operator=(CtorDtor const &) {
274 co_yield 0; // expected-error {{'co_yield' cannot be used in a copy assignment operator}}
275 }
276 void operator=(CtorDtor &&) {
277 co_await a; // expected-error {{'co_await' cannot be used in a move assignment operator}}
278 }
279 void operator=(CtorDtor const &&) {
280 co_await a; // expected-error {{'co_await' cannot be used in a move assignment operator}}
281 }
282 void operator=(int) {
283 co_await a; // OK. Not a special member
Richard Smithcfd53b42015-10-22 06:13:50 +0000284 }
285};
286
Richard Smith744b2242015-11-20 02:54:01 +0000287void unevaluated() {
288 decltype(co_await a); // expected-error {{cannot be used in an unevaluated context}}
289 sizeof(co_await a); // expected-error {{cannot be used in an unevaluated context}}
290 typeid(co_await a); // expected-error {{cannot be used in an unevaluated context}}
291 decltype(co_yield a); // expected-error {{cannot be used in an unevaluated context}}
292 sizeof(co_yield a); // expected-error {{cannot be used in an unevaluated context}}
293 typeid(co_yield a); // expected-error {{cannot be used in an unevaluated context}}
294}
295
Eric Fiselierc8efda72016-10-27 18:43:28 +0000296constexpr auto constexpr_deduced_return_coroutine() {
Richard Smith744b2242015-11-20 02:54:01 +0000297 co_yield 0; // expected-error {{'co_yield' cannot be used in a constexpr function}}
Eric Fiselierc8efda72016-10-27 18:43:28 +0000298 // expected-error@-1 {{'co_yield' cannot be used in a function with a deduced return type}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000299}
300
301void varargs_coroutine(const char *, ...) {
Richard Smith9f690bd2015-10-27 06:02:45 +0000302 co_await a; // expected-error {{'co_await' cannot be used in a varargs function}}
303}
304
Eric Fiselierc8efda72016-10-27 18:43:28 +0000305auto deduced_return_coroutine() {
306 co_await a; // expected-error {{'co_await' cannot be used in a function with a deduced return type}}
307}
308
Richard Smith9f690bd2015-10-27 06:02:45 +0000309struct outer {};
Eric Fiselier20f25cb2017-03-06 23:38:15 +0000310struct await_arg_1 {};
311struct await_arg_2 {};
312
313namespace adl_ns {
314struct coawait_arg_type {};
315awaitable operator co_await(coawait_arg_type);
316}
Richard Smith9f690bd2015-10-27 06:02:45 +0000317
318namespace dependent_operator_co_await_lookup {
319 template<typename T> void await_template(T t) {
320 // no unqualified lookup results
321 co_await t; // expected-error {{no member named 'await_ready' in 'dependent_operator_co_await_lookup::not_awaitable'}}
322 // expected-error@-1 {{call to function 'operator co_await' that is neither visible in the template definition nor found by argument-dependent lookup}}
323 };
324 template void await_template(awaitable);
325
326 struct indirectly_awaitable { indirectly_awaitable(outer); };
327 awaitable operator co_await(indirectly_awaitable); // expected-note {{should be declared prior to}}
328 template void await_template(indirectly_awaitable);
329
330 struct not_awaitable {};
331 template void await_template(not_awaitable); // expected-note {{instantiation}}
332
333 template<typename T> void await_template_2(T t) {
334 // one unqualified lookup result
335 co_await t;
336 };
337 template void await_template(outer); // expected-note {{instantiation}}
338 template void await_template_2(outer);
Eric Fiselier20f25cb2017-03-06 23:38:15 +0000339
340 struct transform_awaitable {};
341 struct transformed {};
342
343 struct transform_promise {
344 typedef transform_awaitable await_arg;
345 coro<transform_promise> get_return_object();
346 transformed initial_suspend();
347 ::adl_ns::coawait_arg_type final_suspend();
348 transformed await_transform(transform_awaitable);
Eric Fiseliera9fdb342017-03-23 00:33:33 +0000349 void unhandled_exception();
Eric Fiselier20f25cb2017-03-06 23:38:15 +0000350 };
351 template <class AwaitArg>
352 struct basic_promise {
353 typedef AwaitArg await_arg;
354 coro<basic_promise> get_return_object();
355 awaitable initial_suspend();
356 awaitable final_suspend();
Eric Fiseliera9fdb342017-03-23 00:33:33 +0000357 void unhandled_exception();
Eric Fiselier20f25cb2017-03-06 23:38:15 +0000358 };
359
360 awaitable operator co_await(await_arg_1);
361
362 template <typename T, typename U>
363 coro<T> await_template_3(U t) {
364 co_await t;
365 }
366
367 template coro<basic_promise<await_arg_1>> await_template_3<basic_promise<await_arg_1>>(await_arg_1);
368
369 template <class T, int I = 0>
370 struct dependent_member {
371 coro<T> mem_fn() const {
372 co_await typename T::await_arg{}; // expected-error {{call to function 'operator co_await'}}}
373 }
374 template <class U>
375 coro<T> dep_mem_fn(U t) {
376 co_await t;
377 }
378 };
379
380 template <>
381 struct dependent_member<long> {
382 // FIXME this diagnostic is terrible
383 coro<transform_promise> mem_fn() const { // expected-error {{no member named 'await_ready' in 'dependent_operator_co_await_lookup::transformed'}}
384 // expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
385 // expected-note@+1 {{function is a coroutine due to use of 'co_await' here}}
386 co_await transform_awaitable{};
387 // expected-error@-1 {{no member named 'await_ready'}}
388 }
389 template <class R, class U>
390 coro<R> dep_mem_fn(U u) { co_await u; }
391 };
392
393 awaitable operator co_await(await_arg_2); // expected-note {{'operator co_await' should be declared prior to the call site}}
394
395 template struct dependent_member<basic_promise<await_arg_1>, 0>;
396 template struct dependent_member<basic_promise<await_arg_2>, 0>; // expected-note {{in instantiation}}
397
398 template <>
399 coro<transform_promise>
400 // FIXME this diagnostic is terrible
401 dependent_member<long>::dep_mem_fn<transform_promise>(int) { // expected-error {{no member named 'await_ready' in 'dependent_operator_co_await_lookup::transformed'}}
402 //expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
403 //expected-note@+1 {{function is a coroutine due to use of 'co_await' here}}
404 co_await transform_awaitable{};
405 // expected-error@-1 {{no member named 'await_ready'}}
406 }
407
408 void operator co_await(transform_awaitable) = delete;
409 awaitable operator co_await(transformed);
410
411 template coro<transform_promise>
412 dependent_member<long>::dep_mem_fn<transform_promise>(transform_awaitable);
413
414 template <>
415 coro<transform_promise> dependent_member<long>::dep_mem_fn<transform_promise>(long) {
416 co_await transform_awaitable{};
417 }
418
419 template <>
420 struct dependent_member<int> {
421 coro<transform_promise> mem_fn() const {
422 co_await transform_awaitable{};
423 }
424 };
425
426 template coro<transform_promise> await_template_3<transform_promise>(transform_awaitable);
427 template struct dependent_member<transform_promise>;
428 template coro<transform_promise> dependent_member<transform_promise>::dep_mem_fn(transform_awaitable);
Richard Smithcfd53b42015-10-22 06:13:50 +0000429}
Richard Smith10610f72015-11-20 22:57:24 +0000430
Richard Smith71d403e2015-11-22 07:33:28 +0000431struct yield_fn_tag {};
Gor Nishanov3e048bb2016-10-04 00:31:16 +0000432template <>
433struct std::experimental::coroutine_traits<void, yield_fn_tag> {
Richard Smith71d403e2015-11-22 07:33:28 +0000434 struct promise_type {
435 // FIXME: add an await_transform overload for functions
436 awaitable yield_value(int());
437 void return_value(int());
Richard Smith2af65c42015-11-24 02:34:39 +0000438
439 suspend_never initial_suspend();
440 suspend_never final_suspend();
441 void get_return_object();
Eric Fiseliera9fdb342017-03-23 00:33:33 +0000442 void unhandled_exception();
Richard Smith71d403e2015-11-22 07:33:28 +0000443 };
444};
445
Richard Smith10610f72015-11-20 22:57:24 +0000446namespace placeholder {
Richard Smith71d403e2015-11-22 07:33:28 +0000447 awaitable f(), f(int); // expected-note 4{{possible target}}
448 int g(), g(int); // expected-note 2{{candidate}}
Richard Smith10610f72015-11-20 22:57:24 +0000449 void x() {
450 co_await f; // expected-error {{reference to overloaded function}}
451 }
452 void y() {
Richard Smith71d403e2015-11-22 07:33:28 +0000453 co_yield g; // expected-error {{no matching member function for call to 'yield_value'}}
Richard Smith10610f72015-11-20 22:57:24 +0000454 }
455 void z() {
456 co_await a;
Richard Smith71d403e2015-11-22 07:33:28 +0000457 co_return g; // expected-error {{address of overloaded function 'g' does not match required type 'int'}}
458 }
459
460 void x(yield_fn_tag) {
461 co_await f; // expected-error {{reference to overloaded function}}
462 }
463 void y(yield_fn_tag) {
464 co_yield g;
465 }
466 void z(yield_fn_tag) {
467 co_await a;
468 co_return g;
Richard Smith10610f72015-11-20 22:57:24 +0000469 }
470}
Richard Smith2af65c42015-11-24 02:34:39 +0000471
472struct bad_promise_1 {
473 suspend_always initial_suspend();
474 suspend_always final_suspend();
Eric Fiseliera9fdb342017-03-23 00:33:33 +0000475 void unhandled_exception();
Richard Smith2af65c42015-11-24 02:34:39 +0000476};
477coro<bad_promise_1> missing_get_return_object() { // expected-error {{no member named 'get_return_object' in 'bad_promise_1'}}
478 co_await a;
479}
480
481struct bad_promise_2 {
482 coro<bad_promise_2> get_return_object();
483 // FIXME: We shouldn't offer a typo-correction here!
484 suspend_always final_suspend(); // expected-note {{here}}
Eric Fiseliera9fdb342017-03-23 00:33:33 +0000485 void unhandled_exception();
Richard Smith2af65c42015-11-24 02:34:39 +0000486};
Eric Fiselier20f25cb2017-03-06 23:38:15 +0000487// FIXME: This shouldn't happen twice
Richard Smith2af65c42015-11-24 02:34:39 +0000488coro<bad_promise_2> missing_initial_suspend() { // expected-error {{no member named 'initial_suspend' in 'bad_promise_2'}}
489 co_await a;
490}
491
492struct bad_promise_3 {
493 coro<bad_promise_3> get_return_object();
494 // FIXME: We shouldn't offer a typo-correction here!
495 suspend_always initial_suspend(); // expected-note {{here}}
Eric Fiseliera9fdb342017-03-23 00:33:33 +0000496 void unhandled_exception();
Richard Smith2af65c42015-11-24 02:34:39 +0000497};
498coro<bad_promise_3> missing_final_suspend() { // expected-error {{no member named 'final_suspend' in 'bad_promise_3'}}
499 co_await a;
500}
501
502struct bad_promise_4 {
503 coro<bad_promise_4> get_return_object();
504 not_awaitable initial_suspend();
505 suspend_always final_suspend();
506};
507// FIXME: This diagnostic is terrible.
508coro<bad_promise_4> bad_initial_suspend() { // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
Eric Fiselier20f25cb2017-03-06 23:38:15 +0000509 // expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
510 co_await a; // expected-note {{function is a coroutine due to use of 'co_await' here}}
Richard Smith2af65c42015-11-24 02:34:39 +0000511}
512
513struct bad_promise_5 {
514 coro<bad_promise_5> get_return_object();
515 suspend_always initial_suspend();
516 not_awaitable final_suspend();
517};
518// FIXME: This diagnostic is terrible.
519coro<bad_promise_5> bad_final_suspend() { // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
Eric Fiselier20f25cb2017-03-06 23:38:15 +0000520 // expected-note@-1 {{call to 'final_suspend' implicitly required by the final suspend point}}
521 co_await a; // expected-note {{function is a coroutine due to use of 'co_await' here}}
Richard Smith2af65c42015-11-24 02:34:39 +0000522}
Eric Fiselier7d5773e2016-09-30 22:38:31 +0000523
Eric Fiselier709d1b32016-10-27 07:30:31 +0000524struct bad_promise_6 {
525 coro<bad_promise_6> get_return_object();
526 suspend_always initial_suspend();
527 suspend_always final_suspend();
Eric Fiseliera9fdb342017-03-23 00:33:33 +0000528 void unhandled_exception();
Eric Fiselier709d1b32016-10-27 07:30:31 +0000529 void return_void();
530 void return_value(int) const;
531 void return_value(int);
532};
533coro<bad_promise_6> bad_implicit_return() { // expected-error {{'bad_promise_6' declares both 'return_value' and 'return_void'}}
534 co_await a;
535}
536
537struct bad_promise_7 {
538 coro<bad_promise_7> get_return_object();
539 suspend_always initial_suspend();
540 suspend_always final_suspend();
541 void return_void();
Eric Fiselier709d1b32016-10-27 07:30:31 +0000542};
Eric Fiseliera9fdb342017-03-23 00:33:33 +0000543coro<bad_promise_7> no_unhandled_exception() { // expected-error {{'bad_promise_7' is required to declare the member 'unhandled_exception()'}}
Eric Fiselier709d1b32016-10-27 07:30:31 +0000544 co_await a;
545}
546
Eric Fiselier20f25cb2017-03-06 23:38:15 +0000547struct bad_promise_base {
548private:
549 void return_void();
550};
551struct bad_promise_8 : bad_promise_base {
Eric Fiselier709d1b32016-10-27 07:30:31 +0000552 coro<bad_promise_8> get_return_object();
553 suspend_always initial_suspend();
554 suspend_always final_suspend();
Eric Fiseliera9fdb342017-03-23 00:33:33 +0000555 void unhandled_exception() __attribute__((unavailable)); // expected-note {{made unavailable}}
556 void unhandled_exception() const; // expected-note {{candidate}}
557 void unhandled_exception(void *) const; // expected-note {{requires 1 argument, but 0 were provided}}
Eric Fiselier709d1b32016-10-27 07:30:31 +0000558};
Eric Fiseliera9fdb342017-03-23 00:33:33 +0000559coro<bad_promise_8> calls_unhandled_exception() {
560 // expected-error@-1 {{call to unavailable member function 'unhandled_exception'}}
Eric Fiselier20f25cb2017-03-06 23:38:15 +0000561 // FIXME: also warn about private 'return_void' here. Even though building
Eric Fiseliera9fdb342017-03-23 00:33:33 +0000562 // the call to unhandled_exception has already failed.
Eric Fiselier709d1b32016-10-27 07:30:31 +0000563 co_await a;
564}
Eric Fiselier7d5773e2016-09-30 22:38:31 +0000565
Eric Fiselier20f25cb2017-03-06 23:38:15 +0000566struct bad_promise_9 {
567 coro<bad_promise_9> get_return_object();
568 suspend_always initial_suspend();
569 suspend_always final_suspend();
570 void await_transform(void *); // expected-note {{candidate}}
571 awaitable await_transform(int) __attribute__((unavailable)); // expected-note {{explicitly made unavailable}}
572 void return_void();
Eric Fiseliera9fdb342017-03-23 00:33:33 +0000573 void unhandled_exception();
Eric Fiselier20f25cb2017-03-06 23:38:15 +0000574};
575coro<bad_promise_9> calls_await_transform() {
576 co_await 42; // expected-error {{call to unavailable member function 'await_transform'}}
577 // expected-note@-1 {{call to 'await_transform' implicitly required by 'co_await' here}}
578}
579
580struct bad_promise_10 {
581 coro<bad_promise_10> get_return_object();
582 suspend_always initial_suspend();
583 suspend_always final_suspend();
584 int await_transform;
585 void return_void();
Eric Fiseliera9fdb342017-03-23 00:33:33 +0000586 void unhandled_exception();
Eric Fiselier20f25cb2017-03-06 23:38:15 +0000587};
588coro<bad_promise_10> bad_coawait() {
589 // FIXME this diagnostic is terrible
590 co_await 42; // expected-error {{called object type 'int' is not a function or function pointer}}
591 // expected-note@-1 {{call to 'await_transform' implicitly required by 'co_await' here}}
592}
593
594struct call_operator {
595 template <class... Args>
596 awaitable operator()(Args...) const { return a; }
597};
598void ret_void();
599struct good_promise_1 {
600 coro<good_promise_1> get_return_object();
601 suspend_always initial_suspend();
602 suspend_always final_suspend();
Eric Fiseliera9fdb342017-03-23 00:33:33 +0000603 void unhandled_exception();
Eric Fiselier20f25cb2017-03-06 23:38:15 +0000604 static const call_operator await_transform;
605 using Fn = void (*)();
606 Fn return_void = ret_void;
607};
608const call_operator good_promise_1::await_transform;
609coro<good_promise_1> ok_static_coawait() {
610 // FIXME this diagnostic is terrible
611 co_await 42;
612}
613
Gor Nishanov3e048bb2016-10-04 00:31:16 +0000614template<> struct std::experimental::coroutine_traits<int, int, const char**>
Eric Fiselier7d5773e2016-09-30 22:38:31 +0000615{ using promise_type = promise; };
616
Eric Fiselierc8efda72016-10-27 18:43:28 +0000617int main(int, const char**) {
618 co_await a; // expected-error {{'co_await' cannot be used in the 'main' function}}
Eric Fiselier7d5773e2016-09-30 22:38:31 +0000619}
Gor Nishanov6dcb0eb2017-03-09 03:09:43 +0000620
621struct good_promise_2 {
622 float get_return_object();
623 suspend_always initial_suspend();
624 suspend_always final_suspend();
625 void return_void();
Eric Fiseliera9fdb342017-03-23 00:33:33 +0000626 void unhandled_exception();
Gor Nishanov6dcb0eb2017-03-09 03:09:43 +0000627};
628template<> struct std::experimental::coroutine_handle<good_promise_2> {};
629
630template<> struct std::experimental::coroutine_traits<float>
631{ using promise_type = good_promise_2; };
632
633float badly_specialized_coro_handle() { // expected-error {{std::experimental::coroutine_handle missing a member named 'from_address'}}
634 //expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
635 co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
636}
Gor Nishanov3aa9eb32017-03-27 23:36:59 +0000637
638struct promise_on_alloc_failure_tag {};
639
640template<>
641struct std::experimental::coroutine_traits<int, promise_on_alloc_failure_tag> {
642 struct promise_type {
643 int get_return_object() {}
644 suspend_always initial_suspend() { return {}; }
645 suspend_always final_suspend() { return {}; }
646 void return_void() {}
647 int get_return_object_on_allocation_failure(); // expected-error{{'promise_type': 'get_return_object_on_allocation_failure()' must be a static member function}}
648 void unhandled_exception();
649 };
650};
651
652extern "C" int f(promise_on_alloc_failure_tag) {
653 co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
654}