blob: a22383cd566b5e1bb3fc97b977fc547e40ad4e55 [file] [log] [blame]
Gor Nishanov4ffb4342016-10-02 03:31:58 +00001// RUN: %clang_cc1 -std=c++14 -fcoroutines-ts -verify %s
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
19
Richard Smith9f690bd2015-10-27 06:02:45 +000020struct awaitable {
21 bool await_ready();
22 void await_suspend(); // FIXME: coroutine_handle
23 void await_resume();
24} a;
25
Richard Smith2af65c42015-11-24 02:34:39 +000026struct suspend_always {
27 bool await_ready() { return false; }
28 void await_suspend() {}
29 void await_resume() {}
30};
31
32struct suspend_never {
33 bool await_ready() { return true; }
34 void await_suspend() {}
35 void await_resume() {}
36};
37
Richard Smith9f690bd2015-10-27 06:02:45 +000038void no_coroutine_traits() {
Gor Nishanov3e048bb2016-10-04 00:31:16 +000039 co_await a; // expected-error {{need to include <experimental/coroutine>}}
Richard Smith9f690bd2015-10-27 06:02:45 +000040}
41
42namespace std {
Gor Nishanov3e048bb2016-10-04 00:31:16 +000043namespace experimental {
44template <typename... T>
45struct coroutine_traits; // expected-note {{declared here}}
46}
47}
Richard Smith9f690bd2015-10-27 06:02:45 +000048
Richard Smith2af65c42015-11-24 02:34:39 +000049template<typename Promise> struct coro {};
Gor Nishanov3e048bb2016-10-04 00:31:16 +000050template <typename Promise, typename... Ps>
51struct std::experimental::coroutine_traits<coro<Promise>, Ps...> {
Richard Smith2af65c42015-11-24 02:34:39 +000052 using promise_type = Promise;
53};
54
Richard Smith9f690bd2015-10-27 06:02:45 +000055void no_specialization() {
Gor Nishanov3e048bb2016-10-04 00:31:16 +000056 co_await a; // expected-error {{implicit instantiation of undefined template 'std::experimental::coroutine_traits<void>'}}
Richard Smith9f690bd2015-10-27 06:02:45 +000057}
58
Gor Nishanov3e048bb2016-10-04 00:31:16 +000059template <typename... T>
60struct std::experimental::coroutine_traits<int, T...> {};
Richard Smith9f690bd2015-10-27 06:02:45 +000061
62int no_promise_type() {
Gor Nishanov3e048bb2016-10-04 00:31:16 +000063 co_await a; // expected-error {{this function cannot be a coroutine: 'std::experimental::coroutine_traits<int>' has no member named 'promise_type'}}
Richard Smith9b2f53e2015-11-19 02:36:35 +000064}
65
Gor Nishanov3e048bb2016-10-04 00:31:16 +000066template <>
67struct std::experimental::coroutine_traits<double, double> { typedef int promise_type; };
Richard Smith9b2f53e2015-11-19 02:36:35 +000068double bad_promise_type(double) {
Gor Nishanov3e048bb2016-10-04 00:31:16 +000069 co_await a; // expected-error {{this function cannot be a coroutine: 'experimental::coroutine_traits<double, double>::promise_type' (aka 'int') is not a class}}
Richard Smith9f690bd2015-10-27 06:02:45 +000070}
71
Gor Nishanov3e048bb2016-10-04 00:31:16 +000072template <>
73struct std::experimental::coroutine_traits<double, int> {
Richard Smith23da82c2015-11-20 22:40:06 +000074 struct promise_type {};
75};
76double bad_promise_type_2(int) {
Gor Nishanov3e048bb2016-10-04 00:31:16 +000077 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 +000078}
79
Richard Smith2af65c42015-11-24 02:34:39 +000080struct promise; // expected-note 2{{forward declaration}}
Eric Fiselier98131312016-10-06 21:23:38 +000081struct promise_void;
82struct void_tag {};
Gor Nishanov3e048bb2016-10-04 00:31:16 +000083template <typename... T>
84struct std::experimental::coroutine_traits<void, T...> { using promise_type = promise; };
Eric Fiselier98131312016-10-06 21:23:38 +000085template <typename... T>
86struct std::experimental::coroutine_traits<void, void_tag, T...>
87{ using promise_type = promise_void; };
Richard Smith9f690bd2015-10-27 06:02:45 +000088
Gor Nishanov3e048bb2016-10-04 00:31:16 +000089namespace std {
90namespace experimental {
91template <typename Promise = void>
92struct coroutine_handle;
93}
94}
95
96// FIXME: This diagnostic is terrible.
Richard Smith9f690bd2015-10-27 06:02:45 +000097void undefined_promise() { // expected-error {{variable has incomplete type 'promise_type'}}
Richard Smith2af65c42015-11-24 02:34:39 +000098 // FIXME: This diagnostic doesn't make any sense.
99 // expected-error@-2 {{incomplete definition of type 'promise'}}
Richard Smith9f690bd2015-10-27 06:02:45 +0000100 co_await a;
101}
102
Richard Smithae3d1472015-11-20 22:47:10 +0000103struct yielded_thing { const char *p; short a, b; };
Richard Smith23da82c2015-11-20 22:40:06 +0000104
Richard Smithd7bed4d2015-11-22 02:57:17 +0000105struct not_awaitable {};
106
Richard Smith23da82c2015-11-20 22:40:06 +0000107struct promise {
Richard Smith2af65c42015-11-24 02:34:39 +0000108 void get_return_object();
109 suspend_always initial_suspend();
110 suspend_always final_suspend();
Richard Smith71d403e2015-11-22 07:33:28 +0000111 awaitable yield_value(int); // expected-note 2{{candidate}}
112 awaitable yield_value(yielded_thing); // expected-note 2{{candidate}}
113 not_awaitable yield_value(void()); // expected-note 2{{candidate}}
Richard Smith71d403e2015-11-22 07:33:28 +0000114 void return_value(int); // expected-note 2{{here}}
Richard Smith23da82c2015-11-20 22:40:06 +0000115};
116
Eric Fiselier98131312016-10-06 21:23:38 +0000117struct promise_void {
118 void get_return_object();
119 suspend_always initial_suspend();
120 suspend_always final_suspend();
Eric Fiselier98131312016-10-06 21:23:38 +0000121 void return_void();
122};
123
Richard Smith23da82c2015-11-20 22:40:06 +0000124void yield() {
125 co_yield 0;
Richard Smithae3d1472015-11-20 22:47:10 +0000126 co_yield {"foo", 1, 2};
127 co_yield {1e100}; // expected-error {{cannot be narrowed}} expected-note {{explicit cast}} expected-warning {{changes value}} expected-warning {{braces around scalar}}
128 co_yield {"foo", __LONG_LONG_MAX__}; // expected-error {{cannot be narrowed}} expected-note {{explicit cast}} expected-warning {{changes value}}
129 co_yield {"foo"};
Richard Smith23da82c2015-11-20 22:40:06 +0000130 co_yield "foo"; // expected-error {{no matching}}
Richard Smithd7bed4d2015-11-22 02:57:17 +0000131 co_yield 1.0;
132 co_yield yield; // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
Richard Smith23da82c2015-11-20 22:40:06 +0000133}
Richard Smith9f690bd2015-10-27 06:02:45 +0000134
Richard Smith4ba66602015-11-22 07:05:16 +0000135void coreturn(int n) {
136 co_await a;
137 if (n == 0)
138 co_return 3;
139 if (n == 1)
Eric Fiselier98131312016-10-06 21:23:38 +0000140 co_return {4}; // expected-warning {{braces around scalar initializer}}
Richard Smith4ba66602015-11-22 07:05:16 +0000141 if (n == 2)
142 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 +0000143 co_return 42;
Richard Smith4ba66602015-11-22 07:05:16 +0000144}
145
Richard Smithcfd53b42015-10-22 06:13:50 +0000146void mixed_yield() {
Richard Smith9f690bd2015-10-27 06:02:45 +0000147 co_yield 0; // expected-note {{use of 'co_yield'}}
148 return; // expected-error {{not allowed in coroutine}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000149}
150
151void mixed_await() {
Richard Smith9f690bd2015-10-27 06:02:45 +0000152 co_await a; // expected-note {{use of 'co_await'}}
153 return; // expected-error {{not allowed in coroutine}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000154}
155
Eric Fiselier98131312016-10-06 21:23:38 +0000156void only_coreturn(void_tag) {
Richard Smith9f690bd2015-10-27 06:02:45 +0000157 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 +0000158}
159
Eric Fiselier98131312016-10-06 21:23:38 +0000160void mixed_coreturn(void_tag, bool b) {
Richard Smithcfd53b42015-10-22 06:13:50 +0000161 if (b)
Richard Smith9f690bd2015-10-27 06:02:45 +0000162 // expected-warning@+1 {{'co_return' used in a function that uses neither}}
163 co_return; // expected-note {{use of 'co_return'}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000164 else
Richard Smith9f690bd2015-10-27 06:02:45 +0000165 return; // expected-error {{not allowed in coroutine}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000166}
167
168struct CtorDtor {
169 CtorDtor() {
170 co_yield 0; // expected-error {{'co_yield' cannot be used in a constructor}}
171 }
Richard Smith9f690bd2015-10-27 06:02:45 +0000172 CtorDtor(awaitable a) {
Richard Smithcfd53b42015-10-22 06:13:50 +0000173 // The spec doesn't say this is ill-formed, but it must be.
Richard Smith9f690bd2015-10-27 06:02:45 +0000174 co_await a; // expected-error {{'co_await' cannot be used in a constructor}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000175 }
176 ~CtorDtor() {
177 co_return 0; // expected-error {{'co_return' cannot be used in a destructor}}
178 }
179 // FIXME: The spec says this is ill-formed.
180 void operator=(CtorDtor&) {
Eric Fiselierc8efda72016-10-27 18:43:28 +0000181 co_yield 0; // expected-error {{'co_yield' cannot be used in a copy assignment operator}}
182 }
183 void operator=(CtorDtor const &) {
184 co_yield 0; // expected-error {{'co_yield' cannot be used in a copy assignment operator}}
185 }
186 void operator=(CtorDtor &&) {
187 co_await a; // expected-error {{'co_await' cannot be used in a move assignment operator}}
188 }
189 void operator=(CtorDtor const &&) {
190 co_await a; // expected-error {{'co_await' cannot be used in a move assignment operator}}
191 }
192 void operator=(int) {
193 co_await a; // OK. Not a special member
Richard Smithcfd53b42015-10-22 06:13:50 +0000194 }
195};
196
Richard Smith744b2242015-11-20 02:54:01 +0000197void unevaluated() {
198 decltype(co_await a); // expected-error {{cannot be used in an unevaluated context}}
199 sizeof(co_await a); // expected-error {{cannot be used in an unevaluated context}}
200 typeid(co_await a); // expected-error {{cannot be used in an unevaluated context}}
201 decltype(co_yield a); // expected-error {{cannot be used in an unevaluated context}}
202 sizeof(co_yield a); // expected-error {{cannot be used in an unevaluated context}}
203 typeid(co_yield a); // expected-error {{cannot be used in an unevaluated context}}
204}
205
Eric Fiselierc8efda72016-10-27 18:43:28 +0000206constexpr auto constexpr_deduced_return_coroutine() {
Richard Smith744b2242015-11-20 02:54:01 +0000207 co_yield 0; // expected-error {{'co_yield' cannot be used in a constexpr function}}
Eric Fiselierc8efda72016-10-27 18:43:28 +0000208 // expected-error@-1 {{'co_yield' cannot be used in a function with a deduced return type}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000209}
210
211void varargs_coroutine(const char *, ...) {
Richard Smith9f690bd2015-10-27 06:02:45 +0000212 co_await a; // expected-error {{'co_await' cannot be used in a varargs function}}
213}
214
Eric Fiselierc8efda72016-10-27 18:43:28 +0000215auto deduced_return_coroutine() {
216 co_await a; // expected-error {{'co_await' cannot be used in a function with a deduced return type}}
217}
218
Richard Smith9f690bd2015-10-27 06:02:45 +0000219struct outer {};
220
221namespace dependent_operator_co_await_lookup {
222 template<typename T> void await_template(T t) {
223 // no unqualified lookup results
224 co_await t; // expected-error {{no member named 'await_ready' in 'dependent_operator_co_await_lookup::not_awaitable'}}
225 // expected-error@-1 {{call to function 'operator co_await' that is neither visible in the template definition nor found by argument-dependent lookup}}
226 };
227 template void await_template(awaitable);
228
229 struct indirectly_awaitable { indirectly_awaitable(outer); };
230 awaitable operator co_await(indirectly_awaitable); // expected-note {{should be declared prior to}}
231 template void await_template(indirectly_awaitable);
232
233 struct not_awaitable {};
234 template void await_template(not_awaitable); // expected-note {{instantiation}}
235
236 template<typename T> void await_template_2(T t) {
237 // one unqualified lookup result
238 co_await t;
239 };
240 template void await_template(outer); // expected-note {{instantiation}}
241 template void await_template_2(outer);
Richard Smithcfd53b42015-10-22 06:13:50 +0000242}
Richard Smith10610f72015-11-20 22:57:24 +0000243
Richard Smith71d403e2015-11-22 07:33:28 +0000244struct yield_fn_tag {};
Gor Nishanov3e048bb2016-10-04 00:31:16 +0000245template <>
246struct std::experimental::coroutine_traits<void, yield_fn_tag> {
Richard Smith71d403e2015-11-22 07:33:28 +0000247 struct promise_type {
248 // FIXME: add an await_transform overload for functions
249 awaitable yield_value(int());
250 void return_value(int());
Richard Smith2af65c42015-11-24 02:34:39 +0000251
252 suspend_never initial_suspend();
253 suspend_never final_suspend();
254 void get_return_object();
Richard Smith71d403e2015-11-22 07:33:28 +0000255 };
256};
257
Richard Smith10610f72015-11-20 22:57:24 +0000258namespace placeholder {
Richard Smith71d403e2015-11-22 07:33:28 +0000259 awaitable f(), f(int); // expected-note 4{{possible target}}
260 int g(), g(int); // expected-note 2{{candidate}}
Richard Smith10610f72015-11-20 22:57:24 +0000261 void x() {
262 co_await f; // expected-error {{reference to overloaded function}}
263 }
264 void y() {
Richard Smith71d403e2015-11-22 07:33:28 +0000265 co_yield g; // expected-error {{no matching member function for call to 'yield_value'}}
Richard Smith10610f72015-11-20 22:57:24 +0000266 }
267 void z() {
268 co_await a;
Richard Smith71d403e2015-11-22 07:33:28 +0000269 co_return g; // expected-error {{address of overloaded function 'g' does not match required type 'int'}}
270 }
271
272 void x(yield_fn_tag) {
273 co_await f; // expected-error {{reference to overloaded function}}
274 }
275 void y(yield_fn_tag) {
276 co_yield g;
277 }
278 void z(yield_fn_tag) {
279 co_await a;
280 co_return g;
Richard Smith10610f72015-11-20 22:57:24 +0000281 }
282}
Richard Smith2af65c42015-11-24 02:34:39 +0000283
284struct bad_promise_1 {
285 suspend_always initial_suspend();
286 suspend_always final_suspend();
287};
288coro<bad_promise_1> missing_get_return_object() { // expected-error {{no member named 'get_return_object' in 'bad_promise_1'}}
289 co_await a;
290}
291
292struct bad_promise_2 {
293 coro<bad_promise_2> get_return_object();
294 // FIXME: We shouldn't offer a typo-correction here!
295 suspend_always final_suspend(); // expected-note {{here}}
296};
297coro<bad_promise_2> missing_initial_suspend() { // expected-error {{no member named 'initial_suspend' in 'bad_promise_2'}}
298 co_await a;
299}
300
301struct bad_promise_3 {
302 coro<bad_promise_3> get_return_object();
303 // FIXME: We shouldn't offer a typo-correction here!
304 suspend_always initial_suspend(); // expected-note {{here}}
305};
306coro<bad_promise_3> missing_final_suspend() { // expected-error {{no member named 'final_suspend' in 'bad_promise_3'}}
307 co_await a;
308}
309
310struct bad_promise_4 {
311 coro<bad_promise_4> get_return_object();
312 not_awaitable initial_suspend();
313 suspend_always final_suspend();
314};
315// FIXME: This diagnostic is terrible.
316coro<bad_promise_4> bad_initial_suspend() { // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
317 co_await a;
318}
319
320struct bad_promise_5 {
321 coro<bad_promise_5> get_return_object();
322 suspend_always initial_suspend();
323 not_awaitable final_suspend();
324};
325// FIXME: This diagnostic is terrible.
326coro<bad_promise_5> bad_final_suspend() { // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
327 co_await a;
328}
Eric Fiselier7d5773e2016-09-30 22:38:31 +0000329
Eric Fiselier709d1b32016-10-27 07:30:31 +0000330struct bad_promise_6 {
331 coro<bad_promise_6> get_return_object();
332 suspend_always initial_suspend();
333 suspend_always final_suspend();
334 void return_void();
335 void return_value(int) const;
336 void return_value(int);
337};
338coro<bad_promise_6> bad_implicit_return() { // expected-error {{'bad_promise_6' declares both 'return_value' and 'return_void'}}
339 co_await a;
340}
341
342struct bad_promise_7 {
343 coro<bad_promise_7> get_return_object();
344 suspend_always initial_suspend();
345 suspend_always final_suspend();
346 void return_void();
347 void set_exception(int *);
348};
349coro<bad_promise_7> no_std_current_exc() {
350 // expected-error@-1 {{you need to include <exception> before defining a coroutine that implicitly uses 'set_exception'}}
351 co_await a;
352}
353
354namespace std {
355int *current_exception();
356}
357
358struct bad_promise_8 {
359 coro<bad_promise_8> get_return_object();
360 suspend_always initial_suspend();
361 suspend_always final_suspend();
362 void return_void();
363 void set_exception(); // expected-note {{function not viable}}
364 void set_exception(int *) __attribute__((unavailable)); // expected-note {{explicitly made unavailable}}
365 void set_exception(void *); // expected-note {{candidate function}}
366};
367coro<bad_promise_8> calls_set_exception() {
368 // expected-error@-1 {{call to unavailable member function 'set_exception'}}
369 co_await a;
370}
Eric Fiselier7d5773e2016-09-30 22:38:31 +0000371
Gor Nishanov3e048bb2016-10-04 00:31:16 +0000372template<> struct std::experimental::coroutine_traits<int, int, const char**>
Eric Fiselier7d5773e2016-09-30 22:38:31 +0000373{ using promise_type = promise; };
374
Eric Fiselierc8efda72016-10-27 18:43:28 +0000375int main(int, const char**) {
376 co_await a; // expected-error {{'co_await' cannot be used in the 'main' function}}
Eric Fiselier7d5773e2016-09-30 22:38:31 +0000377}