blob: 92fdc7947442bdae225781d12db7e9f36af9457e [file] [log] [blame]
Richard Smithcfd53b42015-10-22 06:13:50 +00001// RUN: %clang_cc1 -std=c++14 -fcoroutines -verify %s
2
Eric Fiseliera5465282016-09-29 21:47:39 +00003void no_coroutine_traits_bad_arg_await() {
4 co_await a; // expected-error {{include <coroutine>}}
5 // expected-error@-1 {{use of undeclared identifier 'a'}}
6}
7
8void no_coroutine_traits_bad_arg_yield() {
9 co_yield a; // expected-error {{include <coroutine>}}
10 // expected-error@-1 {{use of undeclared identifier 'a'}}
11}
12
13
14void no_coroutine_traits_bad_arg_return() {
15 co_return a; // expected-error {{include <coroutine>}}
16 // 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() {
39 co_await a; // expected-error {{need to include <coroutine>}}
40}
41
42namespace std {
43 template<typename ...T> struct coroutine_traits; // expected-note {{declared here}}
44};
45
Richard Smith2af65c42015-11-24 02:34:39 +000046template<typename Promise> struct coro {};
47template<typename Promise, typename... Ps>
48struct std::coroutine_traits<coro<Promise>, Ps...> {
49 using promise_type = Promise;
50};
51
Richard Smith9f690bd2015-10-27 06:02:45 +000052void no_specialization() {
53 co_await a; // expected-error {{implicit instantiation of undefined template 'std::coroutine_traits<void>'}}
54}
55
56template<typename ...T> struct std::coroutine_traits<int, T...> {};
57
58int no_promise_type() {
Richard Smith9b2f53e2015-11-19 02:36:35 +000059 co_await a; // expected-error {{this function cannot be a coroutine: 'std::coroutine_traits<int>' has no member named 'promise_type'}}
60}
61
62template<> struct std::coroutine_traits<double, double> { typedef int promise_type; };
63double bad_promise_type(double) {
64 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 +000065}
66
Richard Smith23da82c2015-11-20 22:40:06 +000067template<> struct std::coroutine_traits<double, int> {
68 struct promise_type {};
69};
70double bad_promise_type_2(int) {
71 co_yield 0; // expected-error {{no member named 'yield_value' in 'std::coroutine_traits<double, int>::promise_type'}}
72}
73
Richard Smith2af65c42015-11-24 02:34:39 +000074struct promise; // expected-note 2{{forward declaration}}
Richard Smith9f690bd2015-10-27 06:02:45 +000075template<typename ...T> struct std::coroutine_traits<void, T...> { using promise_type = promise; };
76
77 // FIXME: This diagnostic is terrible.
78void undefined_promise() { // expected-error {{variable has incomplete type 'promise_type'}}
Richard Smith2af65c42015-11-24 02:34:39 +000079 // FIXME: This diagnostic doesn't make any sense.
80 // expected-error@-2 {{incomplete definition of type 'promise'}}
Richard Smith9f690bd2015-10-27 06:02:45 +000081 co_await a;
82}
83
Richard Smithae3d1472015-11-20 22:47:10 +000084struct yielded_thing { const char *p; short a, b; };
Richard Smith23da82c2015-11-20 22:40:06 +000085
Richard Smithd7bed4d2015-11-22 02:57:17 +000086struct not_awaitable {};
87
Richard Smith23da82c2015-11-20 22:40:06 +000088struct promise {
Richard Smith2af65c42015-11-24 02:34:39 +000089 void get_return_object();
90 suspend_always initial_suspend();
91 suspend_always final_suspend();
Richard Smith71d403e2015-11-22 07:33:28 +000092 awaitable yield_value(int); // expected-note 2{{candidate}}
93 awaitable yield_value(yielded_thing); // expected-note 2{{candidate}}
94 not_awaitable yield_value(void()); // expected-note 2{{candidate}}
Richard Smith4ba66602015-11-22 07:05:16 +000095 void return_void();
Richard Smith71d403e2015-11-22 07:33:28 +000096 void return_value(int); // expected-note 2{{here}}
Richard Smith23da82c2015-11-20 22:40:06 +000097};
98
99void yield() {
100 co_yield 0;
Richard Smithae3d1472015-11-20 22:47:10 +0000101 co_yield {"foo", 1, 2};
102 co_yield {1e100}; // expected-error {{cannot be narrowed}} expected-note {{explicit cast}} expected-warning {{changes value}} expected-warning {{braces around scalar}}
103 co_yield {"foo", __LONG_LONG_MAX__}; // expected-error {{cannot be narrowed}} expected-note {{explicit cast}} expected-warning {{changes value}}
104 co_yield {"foo"};
Richard Smith23da82c2015-11-20 22:40:06 +0000105 co_yield "foo"; // expected-error {{no matching}}
Richard Smithd7bed4d2015-11-22 02:57:17 +0000106 co_yield 1.0;
107 co_yield yield; // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
Richard Smith23da82c2015-11-20 22:40:06 +0000108}
Richard Smith9f690bd2015-10-27 06:02:45 +0000109
Richard Smith4ba66602015-11-22 07:05:16 +0000110void coreturn(int n) {
111 co_await a;
112 if (n == 0)
113 co_return 3;
114 if (n == 1)
115 co_return {4};
116 if (n == 2)
117 co_return "foo"; // expected-error {{cannot initialize a parameter of type 'int' with an lvalue of type 'const char [4]'}}
118 co_return;
119}
120
Richard Smithcfd53b42015-10-22 06:13:50 +0000121void mixed_yield() {
Richard Smith9f690bd2015-10-27 06:02:45 +0000122 co_yield 0; // expected-note {{use of 'co_yield'}}
123 return; // expected-error {{not allowed in coroutine}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000124}
125
126void mixed_await() {
Richard Smith9f690bd2015-10-27 06:02:45 +0000127 co_await a; // expected-note {{use of 'co_await'}}
128 return; // expected-error {{not allowed in coroutine}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000129}
130
131void only_coreturn() {
Richard Smith9f690bd2015-10-27 06:02:45 +0000132 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 +0000133}
134
135void mixed_coreturn(bool b) {
Richard Smithcfd53b42015-10-22 06:13:50 +0000136 if (b)
Richard Smith9f690bd2015-10-27 06:02:45 +0000137 // expected-warning@+1 {{'co_return' used in a function that uses neither}}
138 co_return; // expected-note {{use of 'co_return'}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000139 else
Richard Smith9f690bd2015-10-27 06:02:45 +0000140 return; // expected-error {{not allowed in coroutine}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000141}
142
143struct CtorDtor {
144 CtorDtor() {
145 co_yield 0; // expected-error {{'co_yield' cannot be used in a constructor}}
146 }
Richard Smith9f690bd2015-10-27 06:02:45 +0000147 CtorDtor(awaitable a) {
Richard Smithcfd53b42015-10-22 06:13:50 +0000148 // The spec doesn't say this is ill-formed, but it must be.
Richard Smith9f690bd2015-10-27 06:02:45 +0000149 co_await a; // expected-error {{'co_await' cannot be used in a constructor}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000150 }
151 ~CtorDtor() {
152 co_return 0; // expected-error {{'co_return' cannot be used in a destructor}}
153 }
154 // FIXME: The spec says this is ill-formed.
155 void operator=(CtorDtor&) {
156 co_yield 0;
157 }
158};
159
Richard Smith744b2242015-11-20 02:54:01 +0000160void unevaluated() {
161 decltype(co_await a); // expected-error {{cannot be used in an unevaluated context}}
162 sizeof(co_await a); // expected-error {{cannot be used in an unevaluated context}}
163 typeid(co_await a); // expected-error {{cannot be used in an unevaluated context}}
164 decltype(co_yield a); // expected-error {{cannot be used in an unevaluated context}}
165 sizeof(co_yield a); // expected-error {{cannot be used in an unevaluated context}}
166 typeid(co_yield a); // expected-error {{cannot be used in an unevaluated context}}
167}
168
169constexpr void constexpr_coroutine() {
170 co_yield 0; // expected-error {{'co_yield' cannot be used in a constexpr function}}
Richard Smithcfd53b42015-10-22 06:13:50 +0000171}
172
173void varargs_coroutine(const char *, ...) {
Richard Smith9f690bd2015-10-27 06:02:45 +0000174 co_await a; // expected-error {{'co_await' cannot be used in a varargs function}}
175}
176
177struct outer {};
178
179namespace dependent_operator_co_await_lookup {
180 template<typename T> void await_template(T t) {
181 // no unqualified lookup results
182 co_await t; // expected-error {{no member named 'await_ready' in 'dependent_operator_co_await_lookup::not_awaitable'}}
183 // expected-error@-1 {{call to function 'operator co_await' that is neither visible in the template definition nor found by argument-dependent lookup}}
184 };
185 template void await_template(awaitable);
186
187 struct indirectly_awaitable { indirectly_awaitable(outer); };
188 awaitable operator co_await(indirectly_awaitable); // expected-note {{should be declared prior to}}
189 template void await_template(indirectly_awaitable);
190
191 struct not_awaitable {};
192 template void await_template(not_awaitable); // expected-note {{instantiation}}
193
194 template<typename T> void await_template_2(T t) {
195 // one unqualified lookup result
196 co_await t;
197 };
198 template void await_template(outer); // expected-note {{instantiation}}
199 template void await_template_2(outer);
Richard Smithcfd53b42015-10-22 06:13:50 +0000200}
Richard Smith10610f72015-11-20 22:57:24 +0000201
Richard Smith71d403e2015-11-22 07:33:28 +0000202struct yield_fn_tag {};
203template<> struct std::coroutine_traits<void, yield_fn_tag> {
204 struct promise_type {
205 // FIXME: add an await_transform overload for functions
206 awaitable yield_value(int());
207 void return_value(int());
Richard Smith2af65c42015-11-24 02:34:39 +0000208
209 suspend_never initial_suspend();
210 suspend_never final_suspend();
211 void get_return_object();
Richard Smith71d403e2015-11-22 07:33:28 +0000212 };
213};
214
Richard Smith10610f72015-11-20 22:57:24 +0000215namespace placeholder {
Richard Smith71d403e2015-11-22 07:33:28 +0000216 awaitable f(), f(int); // expected-note 4{{possible target}}
217 int g(), g(int); // expected-note 2{{candidate}}
Richard Smith10610f72015-11-20 22:57:24 +0000218 void x() {
219 co_await f; // expected-error {{reference to overloaded function}}
220 }
221 void y() {
Richard Smith71d403e2015-11-22 07:33:28 +0000222 co_yield g; // expected-error {{no matching member function for call to 'yield_value'}}
Richard Smith10610f72015-11-20 22:57:24 +0000223 }
224 void z() {
225 co_await a;
Richard Smith71d403e2015-11-22 07:33:28 +0000226 co_return g; // expected-error {{address of overloaded function 'g' does not match required type 'int'}}
227 }
228
229 void x(yield_fn_tag) {
230 co_await f; // expected-error {{reference to overloaded function}}
231 }
232 void y(yield_fn_tag) {
233 co_yield g;
234 }
235 void z(yield_fn_tag) {
236 co_await a;
237 co_return g;
Richard Smith10610f72015-11-20 22:57:24 +0000238 }
239}
Richard Smith2af65c42015-11-24 02:34:39 +0000240
241struct bad_promise_1 {
242 suspend_always initial_suspend();
243 suspend_always final_suspend();
244};
245coro<bad_promise_1> missing_get_return_object() { // expected-error {{no member named 'get_return_object' in 'bad_promise_1'}}
246 co_await a;
247}
248
249struct bad_promise_2 {
250 coro<bad_promise_2> get_return_object();
251 // FIXME: We shouldn't offer a typo-correction here!
252 suspend_always final_suspend(); // expected-note {{here}}
253};
254coro<bad_promise_2> missing_initial_suspend() { // expected-error {{no member named 'initial_suspend' in 'bad_promise_2'}}
255 co_await a;
256}
257
258struct bad_promise_3 {
259 coro<bad_promise_3> get_return_object();
260 // FIXME: We shouldn't offer a typo-correction here!
261 suspend_always initial_suspend(); // expected-note {{here}}
262};
263coro<bad_promise_3> missing_final_suspend() { // expected-error {{no member named 'final_suspend' in 'bad_promise_3'}}
264 co_await a;
265}
266
267struct bad_promise_4 {
268 coro<bad_promise_4> get_return_object();
269 not_awaitable initial_suspend();
270 suspend_always final_suspend();
271};
272// FIXME: This diagnostic is terrible.
273coro<bad_promise_4> bad_initial_suspend() { // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
274 co_await a;
275}
276
277struct bad_promise_5 {
278 coro<bad_promise_5> get_return_object();
279 suspend_always initial_suspend();
280 not_awaitable final_suspend();
281};
282// FIXME: This diagnostic is terrible.
283coro<bad_promise_5> bad_final_suspend() { // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
284 co_await a;
285}
Eric Fiselier7d5773e2016-09-30 22:38:31 +0000286
287
288template<> struct std::coroutine_traits<int, int, const char**>
289{ using promise_type = promise; };
290
291int main(int, const char**) { // expected-error {{'main' cannot be a coroutine}}
292 co_await a; // expected-note {{function is a coroutine due to use of 'co_await' here}}
293}