blob: 22fdcde1c216315697f8e18eaa1f8d56b09e93d2 [file] [log] [blame]
Gor Nishanovbbe1c072017-02-13 05:05:02 +00001// RUN: %clang_cc1 -std=c++14 -fcoroutines-ts -verify %s -fcxx-exceptions
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}}
Richard Smith23da82c2015-11-20 22:40:06 +0000104};
105
Eric Fiselier98131312016-10-06 21:23:38 +0000106struct promise_void {
107 void get_return_object();
108 suspend_always initial_suspend();
109 suspend_always final_suspend();
Eric Fiselier98131312016-10-06 21:23:38 +0000110 void return_void();
111};
112
Gor Nishanov6dcb0eb2017-03-09 03:09:43 +0000113void no_coroutine_handle() { // expected-error {{std::experimental::coroutine_handle type was not found; include <experimental/coroutine> before defining a coroutine}}
114 //expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
115 co_return 5; //expected-note {{function is a coroutine due to use of 'co_return' here}}
116}
117
118namespace std {
119namespace experimental {
120template <class PromiseType = void>
121struct coroutine_handle {
122 static coroutine_handle from_address(void *);
123};
124template <>
125struct coroutine_handle<void> {
126 template <class PromiseType>
127 coroutine_handle(coroutine_handle<PromiseType>);
128 static coroutine_handle from_address(void *);
129};
130}} // namespace std::experimental
131
Richard Smith23da82c2015-11-20 22:40:06 +0000132void yield() {
133 co_yield 0;
Richard Smithae3d1472015-11-20 22:47:10 +0000134 co_yield {"foo", 1, 2};
135 co_yield {1e100}; // expected-error {{cannot be narrowed}} expected-note {{explicit cast}} expected-warning {{changes value}} expected-warning {{braces around scalar}}
136 co_yield {"foo", __LONG_LONG_MAX__}; // expected-error {{cannot be narrowed}} expected-note {{explicit cast}} expected-warning {{changes value}}
137 co_yield {"foo"};
Richard Smith23da82c2015-11-20 22:40:06 +0000138 co_yield "foo"; // expected-error {{no matching}}
Richard Smithd7bed4d2015-11-22 02:57:17 +0000139 co_yield 1.0;
140 co_yield yield; // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
Richard Smith23da82c2015-11-20 22:40:06 +0000141}
Richard Smith9f690bd2015-10-27 06:02:45 +0000142
Richard Smith4ba66602015-11-22 07:05:16 +0000143void coreturn(int n) {
144 co_await a;
145 if (n == 0)
146 co_return 3;
147 if (n == 1)
Eric Fiselier98131312016-10-06 21:23:38 +0000148 co_return {4}; // expected-warning {{braces around scalar initializer}}
Richard Smith4ba66602015-11-22 07:05:16 +0000149 if (n == 2)
150 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 +0000151 co_return 42;
Richard Smith4ba66602015-11-22 07:05:16 +0000152}
153
Eric Fiselier8d409e82017-03-09 05:01:31 +0000154template <class T>
155void co_await_non_dependent_arg(T) {
156 co_await a;
157}
158template void co_await_non_dependent_arg(int);
159
Richard Smithcfd53b42015-10-22 06:13:50 +0000160void mixed_yield() {
Richard Smith9f690bd2015-10-27 06:02:45 +0000161 co_yield 0; // expected-note {{use of 'co_yield'}}
162 return; // expected-error {{not allowed in coroutine}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000163}
164
165void mixed_await() {
Richard Smith9f690bd2015-10-27 06:02:45 +0000166 co_await a; // expected-note {{use of 'co_await'}}
167 return; // expected-error {{not allowed in coroutine}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000168}
169
Eric Fiselier98131312016-10-06 21:23:38 +0000170void only_coreturn(void_tag) {
Gor Nishanovd97f6bf2017-01-10 00:08:31 +0000171 co_return; // OK
Richard Smithcfd53b42015-10-22 06:13:50 +0000172}
173
Eric Fiselier98131312016-10-06 21:23:38 +0000174void mixed_coreturn(void_tag, bool b) {
Richard Smithcfd53b42015-10-22 06:13:50 +0000175 if (b)
Richard Smith9f690bd2015-10-27 06:02:45 +0000176 co_return; // expected-note {{use of 'co_return'}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000177 else
Richard Smith9f690bd2015-10-27 06:02:45 +0000178 return; // expected-error {{not allowed in coroutine}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000179}
180
181struct CtorDtor {
182 CtorDtor() {
183 co_yield 0; // expected-error {{'co_yield' cannot be used in a constructor}}
184 }
Richard Smith9f690bd2015-10-27 06:02:45 +0000185 CtorDtor(awaitable a) {
Richard Smithcfd53b42015-10-22 06:13:50 +0000186 // The spec doesn't say this is ill-formed, but it must be.
Richard Smith9f690bd2015-10-27 06:02:45 +0000187 co_await a; // expected-error {{'co_await' cannot be used in a constructor}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000188 }
189 ~CtorDtor() {
190 co_return 0; // expected-error {{'co_return' cannot be used in a destructor}}
191 }
192 // FIXME: The spec says this is ill-formed.
193 void operator=(CtorDtor&) {
Eric Fiselierc8efda72016-10-27 18:43:28 +0000194 co_yield 0; // expected-error {{'co_yield' cannot be used in a copy assignment operator}}
195 }
196 void operator=(CtorDtor const &) {
197 co_yield 0; // expected-error {{'co_yield' cannot be used in a copy assignment operator}}
198 }
199 void operator=(CtorDtor &&) {
200 co_await a; // expected-error {{'co_await' cannot be used in a move assignment operator}}
201 }
202 void operator=(CtorDtor const &&) {
203 co_await a; // expected-error {{'co_await' cannot be used in a move assignment operator}}
204 }
205 void operator=(int) {
206 co_await a; // OK. Not a special member
Richard Smithcfd53b42015-10-22 06:13:50 +0000207 }
208};
209
Richard Smith744b2242015-11-20 02:54:01 +0000210void unevaluated() {
211 decltype(co_await a); // expected-error {{cannot be used in an unevaluated context}}
212 sizeof(co_await a); // expected-error {{cannot be used in an unevaluated context}}
213 typeid(co_await a); // expected-error {{cannot be used in an unevaluated context}}
214 decltype(co_yield a); // expected-error {{cannot be used in an unevaluated context}}
215 sizeof(co_yield a); // expected-error {{cannot be used in an unevaluated context}}
216 typeid(co_yield a); // expected-error {{cannot be used in an unevaluated context}}
217}
218
Eric Fiselierc8efda72016-10-27 18:43:28 +0000219constexpr auto constexpr_deduced_return_coroutine() {
Richard Smith744b2242015-11-20 02:54:01 +0000220 co_yield 0; // expected-error {{'co_yield' cannot be used in a constexpr function}}
Eric Fiselierc8efda72016-10-27 18:43:28 +0000221 // expected-error@-1 {{'co_yield' cannot be used in a function with a deduced return type}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000222}
223
224void varargs_coroutine(const char *, ...) {
Richard Smith9f690bd2015-10-27 06:02:45 +0000225 co_await a; // expected-error {{'co_await' cannot be used in a varargs function}}
226}
227
Eric Fiselierc8efda72016-10-27 18:43:28 +0000228auto deduced_return_coroutine() {
229 co_await a; // expected-error {{'co_await' cannot be used in a function with a deduced return type}}
230}
231
Richard Smith9f690bd2015-10-27 06:02:45 +0000232struct outer {};
Eric Fiselier20f25cb2017-03-06 23:38:15 +0000233struct await_arg_1 {};
234struct await_arg_2 {};
235
236namespace adl_ns {
237struct coawait_arg_type {};
238awaitable operator co_await(coawait_arg_type);
239}
Richard Smith9f690bd2015-10-27 06:02:45 +0000240
241namespace dependent_operator_co_await_lookup {
242 template<typename T> void await_template(T t) {
243 // no unqualified lookup results
244 co_await t; // expected-error {{no member named 'await_ready' in 'dependent_operator_co_await_lookup::not_awaitable'}}
245 // expected-error@-1 {{call to function 'operator co_await' that is neither visible in the template definition nor found by argument-dependent lookup}}
246 };
247 template void await_template(awaitable);
248
249 struct indirectly_awaitable { indirectly_awaitable(outer); };
250 awaitable operator co_await(indirectly_awaitable); // expected-note {{should be declared prior to}}
251 template void await_template(indirectly_awaitable);
252
253 struct not_awaitable {};
254 template void await_template(not_awaitable); // expected-note {{instantiation}}
255
256 template<typename T> void await_template_2(T t) {
257 // one unqualified lookup result
258 co_await t;
259 };
260 template void await_template(outer); // expected-note {{instantiation}}
261 template void await_template_2(outer);
Eric Fiselier20f25cb2017-03-06 23:38:15 +0000262
263 struct transform_awaitable {};
264 struct transformed {};
265
266 struct transform_promise {
267 typedef transform_awaitable await_arg;
268 coro<transform_promise> get_return_object();
269 transformed initial_suspend();
270 ::adl_ns::coawait_arg_type final_suspend();
271 transformed await_transform(transform_awaitable);
272 };
273 template <class AwaitArg>
274 struct basic_promise {
275 typedef AwaitArg await_arg;
276 coro<basic_promise> get_return_object();
277 awaitable initial_suspend();
278 awaitable final_suspend();
279 };
280
281 awaitable operator co_await(await_arg_1);
282
283 template <typename T, typename U>
284 coro<T> await_template_3(U t) {
285 co_await t;
286 }
287
288 template coro<basic_promise<await_arg_1>> await_template_3<basic_promise<await_arg_1>>(await_arg_1);
289
290 template <class T, int I = 0>
291 struct dependent_member {
292 coro<T> mem_fn() const {
293 co_await typename T::await_arg{}; // expected-error {{call to function 'operator co_await'}}}
294 }
295 template <class U>
296 coro<T> dep_mem_fn(U t) {
297 co_await t;
298 }
299 };
300
301 template <>
302 struct dependent_member<long> {
303 // FIXME this diagnostic is terrible
304 coro<transform_promise> mem_fn() const { // expected-error {{no member named 'await_ready' in 'dependent_operator_co_await_lookup::transformed'}}
305 // expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
306 // expected-note@+1 {{function is a coroutine due to use of 'co_await' here}}
307 co_await transform_awaitable{};
308 // expected-error@-1 {{no member named 'await_ready'}}
309 }
310 template <class R, class U>
311 coro<R> dep_mem_fn(U u) { co_await u; }
312 };
313
314 awaitable operator co_await(await_arg_2); // expected-note {{'operator co_await' should be declared prior to the call site}}
315
316 template struct dependent_member<basic_promise<await_arg_1>, 0>;
317 template struct dependent_member<basic_promise<await_arg_2>, 0>; // expected-note {{in instantiation}}
318
319 template <>
320 coro<transform_promise>
321 // FIXME this diagnostic is terrible
322 dependent_member<long>::dep_mem_fn<transform_promise>(int) { // expected-error {{no member named 'await_ready' in 'dependent_operator_co_await_lookup::transformed'}}
323 //expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
324 //expected-note@+1 {{function is a coroutine due to use of 'co_await' here}}
325 co_await transform_awaitable{};
326 // expected-error@-1 {{no member named 'await_ready'}}
327 }
328
329 void operator co_await(transform_awaitable) = delete;
330 awaitable operator co_await(transformed);
331
332 template coro<transform_promise>
333 dependent_member<long>::dep_mem_fn<transform_promise>(transform_awaitable);
334
335 template <>
336 coro<transform_promise> dependent_member<long>::dep_mem_fn<transform_promise>(long) {
337 co_await transform_awaitable{};
338 }
339
340 template <>
341 struct dependent_member<int> {
342 coro<transform_promise> mem_fn() const {
343 co_await transform_awaitable{};
344 }
345 };
346
347 template coro<transform_promise> await_template_3<transform_promise>(transform_awaitable);
348 template struct dependent_member<transform_promise>;
349 template coro<transform_promise> dependent_member<transform_promise>::dep_mem_fn(transform_awaitable);
Richard Smithcfd53b42015-10-22 06:13:50 +0000350}
Richard Smith10610f72015-11-20 22:57:24 +0000351
Richard Smith71d403e2015-11-22 07:33:28 +0000352struct yield_fn_tag {};
Gor Nishanov3e048bb2016-10-04 00:31:16 +0000353template <>
354struct std::experimental::coroutine_traits<void, yield_fn_tag> {
Richard Smith71d403e2015-11-22 07:33:28 +0000355 struct promise_type {
356 // FIXME: add an await_transform overload for functions
357 awaitable yield_value(int());
358 void return_value(int());
Richard Smith2af65c42015-11-24 02:34:39 +0000359
360 suspend_never initial_suspend();
361 suspend_never final_suspend();
362 void get_return_object();
Richard Smith71d403e2015-11-22 07:33:28 +0000363 };
364};
365
Richard Smith10610f72015-11-20 22:57:24 +0000366namespace placeholder {
Richard Smith71d403e2015-11-22 07:33:28 +0000367 awaitable f(), f(int); // expected-note 4{{possible target}}
368 int g(), g(int); // expected-note 2{{candidate}}
Richard Smith10610f72015-11-20 22:57:24 +0000369 void x() {
370 co_await f; // expected-error {{reference to overloaded function}}
371 }
372 void y() {
Richard Smith71d403e2015-11-22 07:33:28 +0000373 co_yield g; // expected-error {{no matching member function for call to 'yield_value'}}
Richard Smith10610f72015-11-20 22:57:24 +0000374 }
375 void z() {
376 co_await a;
Richard Smith71d403e2015-11-22 07:33:28 +0000377 co_return g; // expected-error {{address of overloaded function 'g' does not match required type 'int'}}
378 }
379
380 void x(yield_fn_tag) {
381 co_await f; // expected-error {{reference to overloaded function}}
382 }
383 void y(yield_fn_tag) {
384 co_yield g;
385 }
386 void z(yield_fn_tag) {
387 co_await a;
388 co_return g;
Richard Smith10610f72015-11-20 22:57:24 +0000389 }
390}
Richard Smith2af65c42015-11-24 02:34:39 +0000391
392struct bad_promise_1 {
393 suspend_always initial_suspend();
394 suspend_always final_suspend();
395};
396coro<bad_promise_1> missing_get_return_object() { // expected-error {{no member named 'get_return_object' in 'bad_promise_1'}}
397 co_await a;
398}
399
400struct bad_promise_2 {
401 coro<bad_promise_2> get_return_object();
402 // FIXME: We shouldn't offer a typo-correction here!
403 suspend_always final_suspend(); // expected-note {{here}}
404};
Eric Fiselier20f25cb2017-03-06 23:38:15 +0000405// FIXME: This shouldn't happen twice
Richard Smith2af65c42015-11-24 02:34:39 +0000406coro<bad_promise_2> missing_initial_suspend() { // expected-error {{no member named 'initial_suspend' in 'bad_promise_2'}}
407 co_await a;
408}
409
410struct bad_promise_3 {
411 coro<bad_promise_3> get_return_object();
412 // FIXME: We shouldn't offer a typo-correction here!
413 suspend_always initial_suspend(); // expected-note {{here}}
414};
415coro<bad_promise_3> missing_final_suspend() { // expected-error {{no member named 'final_suspend' in 'bad_promise_3'}}
416 co_await a;
417}
418
419struct bad_promise_4 {
420 coro<bad_promise_4> get_return_object();
421 not_awaitable initial_suspend();
422 suspend_always final_suspend();
423};
424// FIXME: This diagnostic is terrible.
425coro<bad_promise_4> bad_initial_suspend() { // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
Eric Fiselier20f25cb2017-03-06 23:38:15 +0000426 // expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
427 co_await a; // expected-note {{function is a coroutine due to use of 'co_await' here}}
Richard Smith2af65c42015-11-24 02:34:39 +0000428}
429
430struct bad_promise_5 {
431 coro<bad_promise_5> get_return_object();
432 suspend_always initial_suspend();
433 not_awaitable final_suspend();
434};
435// FIXME: This diagnostic is terrible.
436coro<bad_promise_5> bad_final_suspend() { // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
Eric Fiselier20f25cb2017-03-06 23:38:15 +0000437 // expected-note@-1 {{call to 'final_suspend' implicitly required by the final suspend point}}
438 co_await a; // expected-note {{function is a coroutine due to use of 'co_await' here}}
Richard Smith2af65c42015-11-24 02:34:39 +0000439}
Eric Fiselier7d5773e2016-09-30 22:38:31 +0000440
Eric Fiselier709d1b32016-10-27 07:30:31 +0000441struct bad_promise_6 {
442 coro<bad_promise_6> get_return_object();
443 suspend_always initial_suspend();
444 suspend_always final_suspend();
445 void return_void();
446 void return_value(int) const;
447 void return_value(int);
448};
449coro<bad_promise_6> bad_implicit_return() { // expected-error {{'bad_promise_6' declares both 'return_value' and 'return_void'}}
450 co_await a;
451}
452
453struct bad_promise_7 {
454 coro<bad_promise_7> get_return_object();
455 suspend_always initial_suspend();
456 suspend_always final_suspend();
457 void return_void();
458 void set_exception(int *);
459};
460coro<bad_promise_7> no_std_current_exc() {
461 // expected-error@-1 {{you need to include <exception> before defining a coroutine that implicitly uses 'set_exception'}}
462 co_await a;
463}
464
465namespace std {
466int *current_exception();
467}
468
Eric Fiselier20f25cb2017-03-06 23:38:15 +0000469struct bad_promise_base {
470private:
471 void return_void();
472};
473struct bad_promise_8 : bad_promise_base {
Eric Fiselier709d1b32016-10-27 07:30:31 +0000474 coro<bad_promise_8> get_return_object();
475 suspend_always initial_suspend();
476 suspend_always final_suspend();
Eric Fiselier709d1b32016-10-27 07:30:31 +0000477 void set_exception(); // expected-note {{function not viable}}
478 void set_exception(int *) __attribute__((unavailable)); // expected-note {{explicitly made unavailable}}
479 void set_exception(void *); // expected-note {{candidate function}}
480};
481coro<bad_promise_8> calls_set_exception() {
482 // expected-error@-1 {{call to unavailable member function 'set_exception'}}
Eric Fiselier20f25cb2017-03-06 23:38:15 +0000483 // FIXME: also warn about private 'return_void' here. Even though building
484 // the call to set_exception has already failed.
Eric Fiselier709d1b32016-10-27 07:30:31 +0000485 co_await a;
486}
Eric Fiselier7d5773e2016-09-30 22:38:31 +0000487
Eric Fiselier20f25cb2017-03-06 23:38:15 +0000488struct bad_promise_9 {
489 coro<bad_promise_9> get_return_object();
490 suspend_always initial_suspend();
491 suspend_always final_suspend();
492 void await_transform(void *); // expected-note {{candidate}}
493 awaitable await_transform(int) __attribute__((unavailable)); // expected-note {{explicitly made unavailable}}
494 void return_void();
495};
496coro<bad_promise_9> calls_await_transform() {
497 co_await 42; // expected-error {{call to unavailable member function 'await_transform'}}
498 // expected-note@-1 {{call to 'await_transform' implicitly required by 'co_await' here}}
499}
500
501struct bad_promise_10 {
502 coro<bad_promise_10> get_return_object();
503 suspend_always initial_suspend();
504 suspend_always final_suspend();
505 int await_transform;
506 void return_void();
507};
508coro<bad_promise_10> bad_coawait() {
509 // FIXME this diagnostic is terrible
510 co_await 42; // expected-error {{called object type 'int' is not a function or function pointer}}
511 // expected-note@-1 {{call to 'await_transform' implicitly required by 'co_await' here}}
512}
513
514struct call_operator {
515 template <class... Args>
516 awaitable operator()(Args...) const { return a; }
517};
518void ret_void();
519struct good_promise_1 {
520 coro<good_promise_1> get_return_object();
521 suspend_always initial_suspend();
522 suspend_always final_suspend();
523 static const call_operator await_transform;
524 using Fn = void (*)();
525 Fn return_void = ret_void;
526};
527const call_operator good_promise_1::await_transform;
528coro<good_promise_1> ok_static_coawait() {
529 // FIXME this diagnostic is terrible
530 co_await 42;
531}
532
Gor Nishanov3e048bb2016-10-04 00:31:16 +0000533template<> struct std::experimental::coroutine_traits<int, int, const char**>
Eric Fiselier7d5773e2016-09-30 22:38:31 +0000534{ using promise_type = promise; };
535
Eric Fiselierc8efda72016-10-27 18:43:28 +0000536int main(int, const char**) {
537 co_await a; // expected-error {{'co_await' cannot be used in the 'main' function}}
Eric Fiselier7d5773e2016-09-30 22:38:31 +0000538}
Gor Nishanov6dcb0eb2017-03-09 03:09:43 +0000539
540struct good_promise_2 {
541 float get_return_object();
542 suspend_always initial_suspend();
543 suspend_always final_suspend();
544 void return_void();
545};
546template<> struct std::experimental::coroutine_handle<good_promise_2> {};
547
548template<> struct std::experimental::coroutine_traits<float>
549{ using promise_type = good_promise_2; };
550
551float badly_specialized_coro_handle() { // expected-error {{std::experimental::coroutine_handle missing a member named 'from_address'}}
552 //expected-note@-1 {{call to 'initial_suspend' implicitly required by the initial suspend point}}
553 co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
554}