1 // RUN: %clang_cc1 -std=c++14 -fcoroutines-ts -verify %s 2 3 void no_coroutine_traits_bad_arg_await() { 4 co_await a; // expected-error {{include <experimental/coroutine>}} 5 // expected-error@-1 {{use of undeclared identifier 'a'}} 6 } 7 8 void no_coroutine_traits_bad_arg_yield() { 9 co_yield a; // expected-error {{include <experimental/coroutine>}} 10 // expected-error@-1 {{use of undeclared identifier 'a'}} 11 } 12 13 14 void no_coroutine_traits_bad_arg_return() { 15 co_return a; // expected-error {{include <experimental/coroutine>}} 16 // expected-error@-1 {{use of undeclared identifier 'a'}} 17 } 18 19 20 struct awaitable { 21 bool await_ready(); 22 void await_suspend(); // FIXME: coroutine_handle 23 void await_resume(); 24 } a; 25 26 struct suspend_always { 27 bool await_ready() { return false; } 28 void await_suspend() {} 29 void await_resume() {} 30 }; 31 32 struct suspend_never { 33 bool await_ready() { return true; } 34 void await_suspend() {} 35 void await_resume() {} 36 }; 37 38 void no_coroutine_traits() { 39 co_await a; // expected-error {{need to include <experimental/coroutine>}} 40 } 41 42 namespace std { 43 namespace experimental { 44 template <typename... T> 45 struct coroutine_traits; // expected-note {{declared here}} 46 } 47 } 48 49 template<typename Promise> struct coro {}; 50 template <typename Promise, typename... Ps> 51 struct std::experimental::coroutine_traits<coro<Promise>, Ps...> { 52 using promise_type = Promise; 53 }; 54 55 void no_specialization() { 56 co_await a; // expected-error {{implicit instantiation of undefined template 'std::experimental::coroutine_traits<void>'}} 57 } 58 59 template <typename... T> 60 struct std::experimental::coroutine_traits<int, T...> {}; 61 62 int no_promise_type() { 63 co_await a; // expected-error {{this function cannot be a coroutine: 'std::experimental::coroutine_traits<int>' has no member named 'promise_type'}} 64 } 65 66 template <> 67 struct std::experimental::coroutine_traits<double, double> { typedef int promise_type; }; 68 double bad_promise_type(double) { 69 co_await a; // expected-error {{this function cannot be a coroutine: 'experimental::coroutine_traits<double, double>::promise_type' (aka 'int') is not a class}} 70 } 71 72 template <> 73 struct std::experimental::coroutine_traits<double, int> { 74 struct promise_type {}; 75 }; 76 double bad_promise_type_2(int) { 77 co_yield 0; // expected-error {{no member named 'yield_value' in 'std::experimental::coroutine_traits<double, int>::promise_type'}} 78 } 79 80 struct promise; // expected-note 2{{forward declaration}} 81 struct promise_void; 82 struct void_tag {}; 83 template <typename... T> 84 struct std::experimental::coroutine_traits<void, T...> { using promise_type = promise; }; 85 template <typename... T> 86 struct std::experimental::coroutine_traits<void, void_tag, T...> 87 { using promise_type = promise_void; }; 88 89 namespace std { 90 namespace experimental { 91 template <typename Promise = void> 92 struct coroutine_handle; 93 } 94 } 95 96 // FIXME: This diagnostic is terrible. 97 void undefined_promise() { // expected-error {{variable has incomplete type 'promise_type'}} 98 // FIXME: This diagnostic doesn't make any sense. 99 // expected-error@-2 {{incomplete definition of type 'promise'}} 100 co_await a; 101 } 102 103 struct yielded_thing { const char *p; short a, b; }; 104 105 struct not_awaitable {}; 106 107 struct promise { 108 void get_return_object(); 109 suspend_always initial_suspend(); 110 suspend_always final_suspend(); 111 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}} 114 void return_value(int); // expected-note 2{{here}} 115 }; 116 117 struct promise_void { 118 void get_return_object(); 119 suspend_always initial_suspend(); 120 suspend_always final_suspend(); 121 void return_void(); 122 }; 123 124 void yield() { 125 co_yield 0; 126 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"}; 130 co_yield "foo"; // expected-error {{no matching}} 131 co_yield 1.0; 132 co_yield yield; // expected-error {{no member named 'await_ready' in 'not_awaitable'}} 133 } 134 135 void coreturn(int n) { 136 co_await a; 137 if (n == 0) 138 co_return 3; 139 if (n == 1) 140 co_return {4}; // expected-warning {{braces around scalar initializer}} 141 if (n == 2) 142 co_return "foo"; // expected-error {{cannot initialize a parameter of type 'int' with an lvalue of type 'const char [4]'}} 143 co_return 42; 144 } 145 146 void mixed_yield() { 147 co_yield 0; // expected-note {{use of 'co_yield'}} 148 return; // expected-error {{not allowed in coroutine}} 149 } 150 151 void mixed_await() { 152 co_await a; // expected-note {{use of 'co_await'}} 153 return; // expected-error {{not allowed in coroutine}} 154 } 155 156 void only_coreturn(void_tag) { 157 co_return; // expected-warning {{'co_return' used in a function that uses neither 'co_await' nor 'co_yield'}} 158 } 159 160 void mixed_coreturn(void_tag, bool b) { 161 if (b) 162 // expected-warning@+1 {{'co_return' used in a function that uses neither}} 163 co_return; // expected-note {{use of 'co_return'}} 164 else 165 return; // expected-error {{not allowed in coroutine}} 166 } 167 168 struct CtorDtor { 169 CtorDtor() { 170 co_yield 0; // expected-error {{'co_yield' cannot be used in a constructor}} 171 } 172 CtorDtor(awaitable a) { 173 // The spec doesn't say this is ill-formed, but it must be. 174 co_await a; // expected-error {{'co_await' cannot be used in a constructor}} 175 } 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&) { 181 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 194 } 195 }; 196 197 void 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 206 constexpr auto constexpr_deduced_return_coroutine() { 207 co_yield 0; // expected-error {{'co_yield' cannot be used in a constexpr function}} 208 // expected-error@-1 {{'co_yield' cannot be used in a function with a deduced return type}} 209 } 210 211 void varargs_coroutine(const char *, ...) { 212 co_await a; // expected-error {{'co_await' cannot be used in a varargs function}} 213 } 214 215 auto deduced_return_coroutine() { 216 co_await a; // expected-error {{'co_await' cannot be used in a function with a deduced return type}} 217 } 218 219 struct outer {}; 220 221 namespace 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); 242 } 243 244 struct yield_fn_tag {}; 245 template <> 246 struct std::experimental::coroutine_traits<void, yield_fn_tag> { 247 struct promise_type { 248 // FIXME: add an await_transform overload for functions 249 awaitable yield_value(int()); 250 void return_value(int()); 251 252 suspend_never initial_suspend(); 253 suspend_never final_suspend(); 254 void get_return_object(); 255 }; 256 }; 257 258 namespace placeholder { 259 awaitable f(), f(int); // expected-note 4{{possible target}} 260 int g(), g(int); // expected-note 2{{candidate}} 261 void x() { 262 co_await f; // expected-error {{reference to overloaded function}} 263 } 264 void y() { 265 co_yield g; // expected-error {{no matching member function for call to 'yield_value'}} 266 } 267 void z() { 268 co_await a; 269 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; 281 } 282 } 283 284 struct bad_promise_1 { 285 suspend_always initial_suspend(); 286 suspend_always final_suspend(); 287 }; 288 coro<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 292 struct 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 }; 297 coro<bad_promise_2> missing_initial_suspend() { // expected-error {{no member named 'initial_suspend' in 'bad_promise_2'}} 298 co_await a; 299 } 300 301 struct 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 }; 306 coro<bad_promise_3> missing_final_suspend() { // expected-error {{no member named 'final_suspend' in 'bad_promise_3'}} 307 co_await a; 308 } 309 310 struct 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. 316 coro<bad_promise_4> bad_initial_suspend() { // expected-error {{no member named 'await_ready' in 'not_awaitable'}} 317 co_await a; 318 } 319 320 struct 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. 326 coro<bad_promise_5> bad_final_suspend() { // expected-error {{no member named 'await_ready' in 'not_awaitable'}} 327 co_await a; 328 } 329 330 struct 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 }; 338 coro<bad_promise_6> bad_implicit_return() { // expected-error {{'bad_promise_6' declares both 'return_value' and 'return_void'}} 339 co_await a; 340 } 341 342 struct 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 }; 349 coro<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 354 namespace std { 355 int *current_exception(); 356 } 357 358 struct 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 }; 367 coro<bad_promise_8> calls_set_exception() { 368 // expected-error@-1 {{call to unavailable member function 'set_exception'}} 369 co_await a; 370 } 371 372 template<> struct std::experimental::coroutine_traits<int, int, const char**> 373 { using promise_type = promise; }; 374 375 int main(int, const char**) { 376 co_await a; // expected-error {{'co_await' cannot be used in the 'main' function}} 377 } 378