cxx1y-generic-lambdas.cpp revision 618c28547a7f7cc785a6c6301f79febf5a584f9e
1// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -emit-llvm -o - %s 2// DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING 3// DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS 4// DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING 5 6namespace explicit_call { 7int test() { 8 auto L = [](auto a) { return a; }; 9 L.operator()(3); 10 L.operator()<char>(3.14); //expected-warning{{implicit conversion}} 11 return 0; 12} 13} //end ns 14 15namespace test_conversion_to_fptr { 16 17void f1(int (*)(int)) { } 18void f2(char (*)(int)) { } // expected-note{{candidate}} 19void g(int (*)(int)) { } // #1 expected-note{{candidate}} 20void g(char (*)(char)) { } // #2 expected-note{{candidate}} 21void h(int (*)(int)) { } // #3 22void h(char (*)(int)) { } // #4 23 24int test() { 25{ 26 auto glambda = [](auto a) { return a; }; 27 glambda(1); 28 f1(glambda); // OK 29 f2(glambda); // expected-error{{no matching function}} 30 g(glambda); // expected-error{{call to 'g' is ambiguous}} 31 h(glambda); // OK: calls #3 since it is convertible from ID 32 33 int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK 34 35} 36{ 37 38 auto L = [](auto a) { return a; }; 39 int (*fp)(int) = L; 40 fp(5); 41 L(3); 42 char (*fc)(char) = L; 43 fc('b'); 44 L('c'); 45 double (*fd)(double) = L; 46 fd(3.14); 47 fd(6.26); 48 L(4.25); 49} 50{ 51 auto L = [](auto a) ->int { return a; }; //expected-note 2{{candidate template ignored}} 52 int (*fp)(int) = L; 53 char (*fc)(char) = L; //expected-error{{no viable conversion}} 54 double (*fd)(double) = L; //expected-error{{no viable conversion}} 55} 56 57} 58 59namespace more_converion_to_ptr_to_function_tests { 60 61 62int test() { 63 { 64 int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK 65 int (*fp2)(int) = [](auto b) -> int { return b; }; 66 int (*fp3)(char) = [](auto c) -> int { return c; }; 67 char (*fp4)(int) = [](auto d) { return d; }; //expected-error{{no viable conversion}}\ 68 //expected-note{{candidate template ignored}} 69 char (*fp5)(char) = [](auto e) -> int { return e; }; //expected-error{{no viable conversion}}\ 70 //expected-note{{candidate template ignored}} 71 72 fp2(3); 73 fp3('\n'); 74 fp3('a'); 75 return 0; 76 } 77} // end test() 78 79template<class ... Ts> void vfun(Ts ... ) { } 80 81int variadic_test() { 82 83 int (*fp)(int, char, double) = [](auto ... a) -> int { vfun(a...); return 4; }; 84 fp(3, '4', 3.14); 85 86 int (*fp2)(int, char, double) = [](auto ... a) { vfun(a...); return 4; }; 87 fp(3, '4', 3.14); 88 return 2; 89} 90 91} // end ns 92 93namespace conversion_operator { 94void test() { 95 auto L = [](auto a) -> int { return a; }; 96 int (*fp)(int) = L; 97 int (&fp2)(int) = [](auto a) { return a; }; // expected-error{{non-const lvalue}} 98 int (&&fp3)(int) = [](auto a) { return a; }; // expected-error{{no viable conversion}}\ 99 //expected-note{{candidate}} 100 } 101} 102} 103 104namespace return_type_deduction_ok { 105 auto l = [](auto a) ->auto { return a; }(2); 106 auto l2 = [](auto a) ->decltype(auto) { return a; }(2); 107 auto l3 = [](auto a) { return a; }(2); 108 109} 110 111namespace generic_lambda_as_default_argument_ok { 112 void test(int i = [](auto a)->int { return a; }(3)) { 113 } 114} 115 116namespace nested_non_capturing_lambda_tests { 117template<class ... Ts> void print(Ts ...) { } 118int test() { 119{ 120 auto L = [](auto a) { 121 return [](auto b) { 122 return b; 123 }; 124 }; 125 auto M = L(3); 126 M(4.15); 127 } 128{ 129 int i = 10; //expected-note{{declared here}} 130 auto L = [](auto a) { 131 return [](auto b) { //expected-note{{begins here}} 132 i = b; //expected-error{{cannot be implicitly captured}} 133 return b; 134 }; 135 }; 136 auto M = L(3); 137 M(4.15); //expected-note{{instantiation}} 138 } 139 { 140 auto L = [](auto a) { 141 print("a = ", a, "\n"); 142 return [](auto b) ->decltype(a) { 143 print("b = ", b, "\n"); 144 return b; 145 }; 146 }; 147 auto M = L(3); 148 M(4.15); 149 } 150 151{ 152 auto L = [](auto a) ->decltype(a) { 153 print("a = ", a, "\n"); 154 return [](auto b) ->decltype(a) { //expected-error{{no viable conversion}}\ 155 //expected-note{{candidate template ignored}} 156 print("b = ", b, "\n"); 157 return b; 158 }; 159 }; 160 auto M = L(3); //expected-note{{in instantiation of}} 161 } 162{ 163 auto L = [](auto a) { 164 print("a = ", a, "\n"); 165 return [](auto ... b) ->decltype(a) { 166 print("b = ", b ..., "\n"); 167 return 4; 168 }; 169 }; 170 auto M = L(3); 171 M(4.15, 3, "fv"); 172} 173 174{ 175 auto L = [](auto a) { 176 print("a = ", a, "\n"); 177 return [](auto ... b) ->decltype(a) { 178 print("b = ", b ..., "\n"); 179 return 4; 180 }; 181 }; 182 auto M = L(3); 183 int (*fp)(double, int, const char*) = M; 184 fp(4.15, 3, "fv"); 185} 186 187{ 188 auto L = [](auto a) { 189 print("a = ", a, "\n"); 190 return [](char b) { 191 return [](auto ... c) ->decltype(b) { 192 print("c = ", c ..., "\n"); 193 return 42; 194 }; 195 }; 196 }; 197 L(4); 198 auto M = L(3); 199 M('a'); 200 auto N = M('x'); 201 N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); 202 char (*np)(const char*, int, const char*, double, const char*, int) = N; 203 np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); 204} 205 206 207{ 208 auto L = [](auto a) { 209 print("a = ", a, "\n"); 210 return [](decltype(a) b) { 211 return [](auto ... c) ->decltype(b) { 212 print("c = ", c ..., "\n"); 213 return 42; 214 }; 215 }; 216 }; 217 L('4'); 218 auto M = L('3'); 219 M('a'); 220 auto N = M('x'); 221 N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); 222 char (*np)(const char*, int, const char*, double, const char*, int) = N; 223 np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); 224} 225 226 227{ 228 struct X { 229 static void foo(double d) { } 230 void test() { 231 auto L = [](auto a) { 232 print("a = ", a, "\n"); 233 foo(a); 234 return [](decltype(a) b) { 235 foo(b); 236 foo(sizeof(a) + sizeof(b)); 237 return [](auto ... c) ->decltype(b) { 238 print("c = ", c ..., "\n"); 239 foo(decltype(b){}); 240 foo(sizeof(decltype(a)*) + sizeof(decltype(b)*)); 241 return 42; 242 }; 243 }; 244 }; 245 L('4'); 246 auto M = L('3'); 247 M('a'); 248 auto N = M('x'); 249 N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); 250 char (*np)(const char*, int, const char*, double, const char*, int) = N; 251 np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); 252 } 253}; 254X x; 255x.test(); 256} 257// Make sure we can escape the function 258{ 259 struct X { 260 static void foo(double d) { } 261 auto test() { 262 auto L = [](auto a) { 263 print("a = ", a, "\n"); 264 foo(a); 265 return [](decltype(a) b) { 266 foo(b); 267 foo(sizeof(a) + sizeof(b)); 268 return [](auto ... c) ->decltype(b) { 269 print("c = ", c ..., "\n"); 270 foo(decltype(b){}); 271 foo(sizeof(decltype(a)*) + sizeof(decltype(b)*)); 272 return 42; 273 }; 274 }; 275 }; 276 return L; 277 } 278}; 279 X x; 280 auto L = x.test(); 281 L('4'); 282 auto M = L('3'); 283 M('a'); 284 auto N = M('x'); 285 N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); 286 char (*np)(const char*, int, const char*, double, const char*, int) = N; 287 np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); 288} 289 290{ 291 struct X { 292 static void foo(double d) { } 293 auto test() { 294 auto L = [](auto a) { 295 print("a = ", a, "\n"); 296 foo(a); 297 return [](decltype(a) b) { 298 foo(b); 299 foo(sizeof(a) + sizeof(b)); 300 return [](auto ... c) { 301 print("c = ", c ..., "\n"); 302 foo(decltype(b){}); 303 foo(sizeof(decltype(a)*) + sizeof(decltype(b)*)); 304 return [](decltype(c) ... d) ->decltype(a) { //expected-note{{candidate}} 305 print("d = ", d ..., "\n"); 306 foo(decltype(b){}); 307 foo(sizeof(decltype(a)*) + sizeof(decltype(b)*)); 308 return decltype(a){}; 309 }; 310 }; 311 }; 312 }; 313 return L; 314 } 315}; 316 X x; 317 auto L = x.test(); 318 L('4'); 319 auto M = L('3'); 320 M('a'); 321 auto N = M('x'); 322 auto O = N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); 323 char (*np)(const char*, int, const char*, double, const char*, int) = O; 324 np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); 325 int (*np2)(const char*, int, const char*, double, const char*, int) = O; // expected-error{{no viable conversion}} 326 327} 328} // end test() 329 330namespace wrapped_within_templates { 331 332namespace explicit_return { 333template<class T> int fooT(T t) { 334 auto L = [](auto a) -> void { 335 auto M = [](char b) -> void { 336 auto N = [](auto c) -> void { 337 int x = 0; 338 x = sizeof(a); 339 x = sizeof(b); 340 x = sizeof(c); 341 }; 342 N('a'); 343 N(decltype(a){}); 344 }; 345 }; 346 L(t); 347 L(3.14); 348 return 0; 349} 350 351int run = fooT('a') + fooT(3.14); 352 353} // end explicit_return 354 355namespace implicit_return_deduction { 356template<class T> auto fooT(T t) { 357 auto L = [](auto a) { 358 auto M = [](char b) { 359 auto N = [](auto c) { 360 int x = 0; 361 x = sizeof(a); 362 x = sizeof(b); 363 x = sizeof(c); 364 }; 365 N('a'); 366 N(decltype(a){}); 367 }; 368 }; 369 L(t); 370 L(3.14); 371 return 0; 372} 373 374int run = fooT('a') + fooT(3.14); 375 376template<class ... Ts> void print(Ts ... ts) { } 377 378template<class F, class ... Rest> using first = F; 379 380template<class ... Ts> auto fooV(Ts ... ts) { 381 auto L = [](auto ... a) { 382 auto M = [](decltype(a) ... b) { 383 auto N = [](auto c) { 384 int x = 0; 385 x = sizeof...(a); 386 x = sizeof...(b); 387 x = sizeof(c); 388 }; 389 N('a'); 390 N(N); 391 N(first<Ts...>{}); 392 }; 393 M(a...); 394 print("a = ", a..., "\n"); 395 }; 396 L(L, ts...); 397 print("ts = ", ts..., "\n"); 398 return 0; 399} 400 401int run2 = fooV(3.14, " ", '4', 5) + fooV("BC", 3, 2.77, 'A', float{}, short{}, unsigned{}); 402 403} //implicit_return_deduction 404 405 406} //wrapped_within_templates 407 408namespace at_ns_scope { 409 void foo(double d) { } 410 auto test() { 411 auto L = [](auto a) { 412 print("a = ", a, "\n"); 413 foo(a); 414 return [](decltype(a) b) { 415 foo(b); 416 foo(sizeof(a) + sizeof(b)); 417 return [](auto ... c) { 418 print("c = ", c ..., "\n"); 419 foo(decltype(b){}); 420 foo(sizeof(decltype(a)*) + sizeof(decltype(b)*)); 421 return [](decltype(c) ... d) ->decltype(a) { //expected-note{{candidate}} 422 print("d = ", d ..., "\n"); 423 foo(decltype(b){}); 424 foo(sizeof(decltype(a)*) + sizeof(decltype(b)*)); 425 return decltype(a){}; 426 }; 427 }; 428 }; 429 }; 430 return L; 431 } 432auto L = test(); 433auto L_test = L('4'); 434auto M = L('3'); 435auto M_test = M('a'); 436auto N = M('x'); 437auto O = N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); 438char (*np)(const char*, int, const char*, double, const char*, int) = O; 439auto NP_result = np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); 440int (*np2)(const char*, int, const char*, double, const char*, int) = O; // expected-error{{no viable conversion}} 441 442 443 444} 445 446namespace variadic_tests_1 { 447template<class ... Ts> void print(Ts ... ts) { } 448 449template<class F, class ... Rest> using FirstType = F; 450template<class F, class ... Rest> F& FirstArg(F& f, Rest...) { return f; } 451 452template<class ... Ts> int fooV(Ts ... ts) { 453 auto L = [](auto ... a) -> void { 454 auto M = [](decltype(a) ... b) -> void { 455 auto N = [](auto c) -> void { 456 int x = 0; 457 x = sizeof...(a); 458 x = sizeof...(b); 459 x = sizeof(c); 460 }; 461 N('a'); 462 N(N); 463 N(FirstType<Ts...>{}); 464 }; 465 M(a...); 466 print("a = ", a..., "\n"); 467 }; 468 L(L, ts...); 469 print("ts = ", ts..., "\n"); 470 return 0; 471} 472 473int run2 = fooV(3.14, " ", '4', 5) + fooV("BC", 3, 2.77, 'A', float{}, short{}, unsigned{}); 474 475namespace more_variadic_1 { 476 477template<class ... Ts> int fooV(Ts ... ts) { 478 auto L = [](auto ... a) { 479 auto M = [](decltype(a) ... b) -> void { 480 auto N = [](auto c) -> void { 481 int x = 0; 482 x = sizeof...(a); 483 x = sizeof...(b); 484 x = sizeof(c); 485 }; 486 N('a'); 487 N(N); 488 N(FirstType<Ts...>{}); 489 }; 490 M(a...); 491 return M; 492 }; 493 auto M = L(L, ts...); 494 decltype(L(L, ts...)) (*fp)(decltype(L), decltype(ts) ...) = L; 495 void (*fp2)(decltype(L), decltype(ts) ...) = L(L, ts...); 496 497 { 498 auto L = [](auto ... a) { 499 auto M = [](decltype(a) ... b) { 500 auto N = [](auto c) -> void { 501 int x = 0; 502 x = sizeof...(a); 503 x = sizeof...(b); 504 x = sizeof(c); 505 }; 506 N('a'); 507 N(N); 508 N(FirstType<Ts...>{}); 509 return N; 510 }; 511 M(a...); 512 return M; 513 }; 514 auto M = L(L, ts...); 515 decltype(L(L, ts...)) (*fp)(decltype(L), decltype(ts) ...) = L; 516 fp(L, ts...); 517 decltype(L(L, ts...)(L, ts...)) (*fp2)(decltype(L), decltype(ts) ...) = L(L, ts...); 518 fp2 = fp(L, ts...); 519 void (*fp3)(char) = fp2(L, ts...); 520 fp3('a'); 521 } 522 return 0; 523} 524 525int run2 = fooV(3.14, " ", '4', 5) + fooV("BC", 3, 2.77, 'A', float{}, short{}, unsigned{}); 526 527 528} //end ns more_variadic_1 529 530} // end ns variadic_tests_1 531 532namespace at_ns_scope_within_class_member { 533 struct X { 534 static void foo(double d) { } 535 auto test() { 536 auto L = [](auto a) { 537 print("a = ", a, "\n"); 538 foo(a); 539 return [](decltype(a) b) { 540 foo(b); 541 foo(sizeof(a) + sizeof(b)); 542 return [](auto ... c) { 543 print("c = ", c ..., "\n"); 544 foo(decltype(b){}); 545 foo(sizeof(decltype(a)*) + sizeof(decltype(b)*)); 546 return [](decltype(c) ... d) ->decltype(a) { //expected-note{{candidate}} 547 print("d = ", d ..., "\n"); 548 foo(decltype(b){}); 549 foo(sizeof(decltype(a)*) + sizeof(decltype(b)*)); 550 return decltype(a){}; 551 }; 552 }; 553 }; 554 }; 555 return L; 556 } 557}; 558X x; 559auto L = x.test(); 560auto L_test = L('4'); 561auto M = L('3'); 562auto M_test = M('a'); 563auto N = M('x'); 564auto O = N("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); 565char (*np)(const char*, int, const char*, double, const char*, int) = O; 566auto NP_result = np("\n3 = ", 3, "\n6.14 = ", 6.14, "\n4'123'456 = ", 4'123'456); 567int (*np2)(const char*, int, const char*, double, const char*, int) = O; // expected-error{{no viable conversion}} 568 569} //end at_ns_scope_within_class_member 570 571 572namespace nested_generic_lambdas_123 { 573void test() { 574 auto L = [](auto a) -> int { 575 auto M = [](auto b, decltype(a) b2) -> int { 576 return 1; 577 }; 578 M(a, a); 579 }; 580 L(3); 581} 582template<class T> void foo(T) { 583 auto L = [](auto a) { return a; }; 584} 585template void foo(int); 586} // end ns nested_generic_lambdas_123 587 588 589} // end ns nested_non_capturing_lambda_tests 590