1 // RUN: %clang_cc1 -triple x86_64-windows -fsyntax-only -verify -fblocks -fcxx-exceptions -fms-extensions %s -Wno-unreachable-code 2 // RUN: %clang_cc1 -triple x86_64-windows -fsyntax-only -verify -fblocks -fcxx-exceptions -fms-extensions -std=gnu++11 %s -Wno-unreachable-code 3 4 namespace testInvalid { 5 Invalid inv; // expected-error {{unknown type name}} 6 // Make sure this doesn't assert. 7 void fn() 8 { 9 int c = 0; 10 if (inv) 11 Here: ; 12 goto Here; 13 } 14 } 15 16 namespace test0 { 17 struct D { ~D(); }; 18 19 int f(bool b) { 20 if (b) { 21 D d; 22 goto end; 23 } 24 25 end: 26 return 1; 27 } 28 } 29 30 namespace test1 { 31 struct C { C(); }; 32 33 int f(bool b) { 34 if (b) 35 goto foo; // expected-error {{cannot jump}} 36 C c; // expected-note {{jump bypasses variable initialization}} 37 foo: 38 return 1; 39 } 40 } 41 42 namespace test2 { 43 struct C { C(); }; 44 45 int f(void **ip) { 46 static void *ips[] = { &&lbl1, &&lbl2 }; 47 48 C c; 49 goto *ip; 50 lbl1: 51 return 0; 52 lbl2: 53 return 1; 54 } 55 } 56 57 namespace test3 { 58 struct C { C(); }; 59 60 int f(void **ip) { 61 static void *ips[] = { &&lbl1, &&lbl2 }; 62 63 goto *ip; 64 lbl1: { 65 C c; 66 return 0; 67 } 68 lbl2: 69 return 1; 70 } 71 } 72 73 namespace test4 { 74 struct C { C(); }; 75 struct D { ~D(); }; 76 77 int f(void **ip) { 78 static void *ips[] = { &&lbl1, &&lbl2 }; 79 80 C c0; 81 82 goto *ip; // expected-error {{cannot jump}} 83 C c1; // expected-note {{jump bypasses variable initialization}} 84 lbl1: // expected-note {{possible target of indirect goto}} 85 return 0; 86 lbl2: 87 return 1; 88 } 89 } 90 91 namespace test5 { 92 struct C { C(); }; 93 struct D { ~D(); }; 94 95 int f(void **ip) { 96 static void *ips[] = { &&lbl1, &&lbl2 }; 97 C c0; 98 99 goto *ip; 100 lbl1: // expected-note {{possible target of indirect goto}} 101 return 0; 102 lbl2: 103 if (ip[1]) { 104 D d; // expected-note {{jump exits scope of variable with non-trivial destructor}} 105 ip += 2; 106 goto *ip; // expected-error {{cannot jump}} 107 } 108 return 1; 109 } 110 } 111 112 namespace test6 { 113 struct C { C(); }; 114 115 unsigned f(unsigned s0, unsigned s1, void **ip) { 116 static void *ips[] = { &&lbl1, &&lbl2, &&lbl3, &&lbl4 }; 117 C c0; 118 119 goto *ip; 120 lbl1: 121 s0++; 122 goto *++ip; 123 lbl2: 124 s0 -= s1; 125 goto *++ip; 126 lbl3: { 127 unsigned tmp = s0; 128 s0 = s1; 129 s1 = tmp; 130 goto *++ip; 131 } 132 lbl4: 133 return s0; 134 } 135 } 136 137 // C++0x says it's okay to skip non-trivial initializers on static 138 // locals, and we implement that in '03 as well. 139 namespace test7 { 140 struct C { C(); }; 141 142 void test() { 143 goto foo; 144 static C c; 145 foo: 146 return; 147 } 148 } 149 150 // PR7789 151 namespace test8 { 152 void test1(int c) { 153 switch (c) { 154 case 0: 155 int x = 56; // expected-note {{jump bypasses variable initialization}} 156 case 1: // expected-error {{cannot jump}} 157 x = 10; 158 } 159 } 160 161 void test2() { 162 goto l2; // expected-error {{cannot jump}} 163 l1: int x = 5; // expected-note {{jump bypasses variable initialization}} 164 l2: x++; 165 } 166 } 167 168 namespace test9 { 169 struct S { int i; }; 170 void test1() { 171 goto foo; 172 S s; 173 foo: 174 return; 175 } 176 unsigned test2(unsigned x, unsigned y) { 177 switch (x) { 178 case 2: 179 S s; 180 if (y > 42) return x + y; 181 default: 182 return x - 2; 183 } 184 } 185 } 186 187 // http://llvm.org/PR10462 188 namespace PR10462 { 189 enum MyEnum { 190 something_valid, 191 something_invalid 192 }; 193 194 bool recurse() { 195 MyEnum K; 196 switch (K) { // do not warn that 'something_invalid' is not listed; 197 // 'what_am_i_thinking' might have been intended to be that case. 198 case something_valid: 199 case what_am_i_thinking: // expected-error {{use of undeclared identifier}} 200 int *X = 0; 201 if (recurse()) { 202 } 203 204 break; 205 } 206 } 207 } 208 209 namespace test10 { 210 int test() { 211 static void *ps[] = { &&a0 }; 212 goto *&&a0; // expected-error {{cannot jump}} 213 int a = 3; // expected-note {{jump bypasses variable initialization}} 214 a0: 215 return 0; 216 } 217 } 218 219 // pr13812 220 namespace test11 { 221 struct C { 222 C(int x); 223 ~C(); 224 }; 225 void f(void **ip) { 226 static void *ips[] = { &&l0 }; 227 l0: // expected-note {{possible target of indirect goto}} 228 C c0 = 42; // expected-note {{jump exits scope of variable with non-trivial destructor}} 229 goto *ip; // expected-error {{cannot jump}} 230 } 231 } 232 233 namespace test12 { 234 struct C { 235 C(int x); 236 ~C(); 237 }; 238 void f(void **ip) { 239 static void *ips[] = { &&l0 }; 240 const C c0 = 17; 241 l0: // expected-note {{possible target of indirect goto}} 242 const C &c1 = 42; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}} 243 const C &c2 = c0; 244 goto *ip; // expected-error {{cannot jump}} 245 } 246 } 247 248 namespace test13 { 249 struct C { 250 C(int x); 251 ~C(); 252 int i; 253 }; 254 void f(void **ip) { 255 static void *ips[] = { &&l0 }; 256 l0: // expected-note {{possible target of indirect goto}} 257 const int &c1 = C(1).i; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}} 258 goto *ip; // expected-error {{cannot jump}} 259 } 260 } 261 262 namespace test14 { 263 struct C { 264 C(int x); 265 ~C(); 266 operator int&() const; 267 }; 268 void f(void **ip) { 269 static void *ips[] = { &&l0 }; 270 l0: 271 // no warning since the C temporary is destructed before the goto. 272 const int &c1 = C(1); 273 goto *ip; 274 } 275 } 276 277 // PR14225 278 namespace test15 { 279 void f1() try { 280 goto x; // expected-error {{cannot jump}} 281 } catch(...) { // expected-note {{jump bypasses initialization of catch block}} 282 x: ; 283 } 284 void f2() try { // expected-note {{jump bypasses initialization of try block}} 285 x: ; 286 } catch(...) { 287 goto x; // expected-error {{cannot jump}} 288 } 289 } 290 291 namespace test16 { 292 struct S { int n; }; 293 int f() { 294 goto x; // expected-error {{cannot jump}} 295 const S &s = S(); // expected-note {{jump bypasses variable initialization}} 296 x: return s.n; 297 } 298 } 299 300 #if __cplusplus >= 201103L 301 namespace test17 { 302 struct S { int get(); private: int n; }; 303 int f() { 304 goto x; // expected-error {{cannot jump}} 305 S s = {}; // expected-note {{jump bypasses variable initialization}} 306 x: return s.get(); 307 } 308 } 309 #endif 310 311 namespace test18 { 312 struct A { ~A(); }; 313 struct B { const int &r; const A &a; }; 314 int f() { 315 void *p = &&x; 316 const A a = A(); 317 x: 318 B b = { 0, a }; // ok 319 goto *p; 320 } 321 int g() { 322 void *p = &&x; 323 x: // expected-note {{possible target of indirect goto}} 324 B b = { 0, A() }; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}} 325 goto *p; // expected-error {{cannot jump}} 326 } 327 } 328 329 #if __cplusplus >= 201103L 330 namespace std { 331 typedef decltype(sizeof(int)) size_t; 332 template<typename T> struct initializer_list { 333 const T *begin; 334 size_t size; 335 initializer_list(const T *, size_t); 336 }; 337 } 338 namespace test19 { 339 struct A { ~A(); }; 340 341 int f() { 342 void *p = &&x; 343 A a; 344 x: // expected-note {{possible target of indirect goto}} 345 std::initializer_list<A> il = { a }; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}} 346 goto *p; // expected-error {{cannot jump}} 347 } 348 } 349 350 namespace test20 { 351 struct A { ~A(); }; 352 struct B { 353 const A &a; 354 }; 355 356 int f() { 357 void *p = &&x; 358 A a; 359 x: 360 std::initializer_list<B> il = { 361 a, 362 a 363 }; 364 goto *p; 365 } 366 int g() { 367 void *p = &&x; 368 A a; 369 x: // expected-note {{possible target of indirect goto}} 370 std::initializer_list<B> il = { 371 a, 372 { A() } // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}} 373 }; 374 goto *p; // expected-error {{cannot jump}} 375 } 376 } 377 #endif 378 379 namespace test21 { 380 template<typename T> void f() { 381 goto x; // expected-error {{cannot jump}} 382 T t; // expected-note {{bypasses}} 383 x: return; 384 } 385 386 template void f<int>(); 387 struct X { ~X(); }; 388 template void f<X>(); // expected-note {{instantiation of}} 389 } 390 391 namespace PR18217 { 392 typedef int *X; 393 394 template <typename T> 395 class MyCl { 396 T mem; 397 }; 398 399 class Source { 400 MyCl<X> m; 401 public: 402 int getKind() const; 403 }; 404 405 bool b; 406 template<typename TT> 407 static void foo(const Source &SF, MyCl<TT *> Source::*m) { 408 switch (SF.getKind()) { 409 case 1: return; 410 case 2: break; 411 case 3: 412 case 4: return; 413 }; 414 if (b) { 415 auto &y = const_cast<MyCl<TT *> &>(SF.*m); // expected-warning 0-1{{extension}} 416 } 417 } 418 419 int Source::getKind() const { 420 foo(*this, &Source::m); 421 return 0; 422 } 423 } 424 425 namespace test_recovery { 426 // Test that jump scope checking recovers when there are unspecified errors 427 // in the function declaration or body. 428 429 void test(nexist, int c) { // expected-error {{}} 430 nexist_fn(); // expected-error {{}} 431 goto nexist_label; // expected-error {{use of undeclared label}} 432 goto a0; // expected-error {{cannot jump}} 433 int a = 0; // expected-note {{jump bypasses variable initialization}} 434 a0:; 435 436 switch (c) { 437 case $: // expected-error {{}} 438 case 0: 439 int x = 56; // expected-note {{jump bypasses variable initialization}} 440 case 1: // expected-error {{cannot jump}} 441 x = 10; 442 } 443 } 444 } 445 446 namespace seh { 447 448 // Jumping into SEH try blocks is not permitted. 449 450 void jump_into_except() { 451 goto into_try_except_try; // expected-error {{cannot jump from this goto statement to its label}} 452 __try { // expected-note {{jump bypasses initialization of __try block}} 453 into_try_except_try: 454 ; 455 } __except(0) { 456 } 457 458 goto into_try_except_except; // expected-error {{cannot jump from this goto statement to its label}} 459 __try { 460 } __except(0) { // expected-note {{jump bypasses initialization of __except block}} 461 into_try_except_except: 462 ; 463 } 464 } 465 466 void jump_into_finally() { 467 goto into_try_except_try; // expected-error {{cannot jump from this goto statement to its label}} 468 __try { // expected-note {{jump bypasses initialization of __try block}} 469 into_try_except_try: 470 ; 471 } __finally { 472 } 473 474 goto into_try_except_finally; // expected-error {{cannot jump from this goto statement to its label}} 475 __try { 476 } __finally { // expected-note {{jump bypasses initialization of __finally block}} 477 into_try_except_finally: 478 ; 479 } 480 } 481 482 // Jumping out of SEH try blocks ok in general. (Jumping out of a __finally 483 // has undefined behavior.) 484 485 void jump_out_of_except() { 486 __try { 487 goto out_of_except_try; 488 } __except(0) { 489 } 490 out_of_except_try: 491 ; 492 493 __try { 494 } __except(0) { 495 goto out_of_except_except; 496 } 497 out_of_except_except: 498 ; 499 } 500 501 void jump_out_of_finally() { 502 __try { 503 goto out_of_finally_try; 504 } __finally { 505 } 506 out_of_finally_try: 507 ; 508 509 __try { 510 } __finally { 511 goto out_of_finally_finally; // expected-warning {{jump out of __finally block has undefined behavior}} 512 } 513 514 __try { 515 } __finally { 516 goto *&&out_of_finally_finally; // expected-warning {{jump out of __finally block has undefined behavior}} 517 } 518 out_of_finally_finally: 519 ; 520 } 521 522 // Jumping between protected scope and handler is not permitted. 523 524 void jump_try_except() { 525 __try { 526 goto from_try_to_except; // expected-error {{cannot jump from this goto statement to its label}} 527 } __except(0) { // expected-note {{jump bypasses initialization of __except block}} 528 from_try_to_except: 529 ; 530 } 531 532 __try { // expected-note {{jump bypasses initialization of __try block}} 533 from_except_to_try: 534 ; 535 } __except(0) { 536 goto from_except_to_try; // expected-error {{cannot jump from this goto statement to its label}} 537 } 538 } 539 540 void jump_try_finally() { 541 __try { 542 goto from_try_to_finally; // expected-error {{cannot jump from this goto statement to its label}} 543 } __finally { // expected-note {{jump bypasses initialization of __finally block}} 544 from_try_to_finally: 545 ; 546 } 547 548 __try { // expected-note {{jump bypasses initialization of __try block}} 549 from_finally_to_try: 550 ; 551 } __finally { 552 goto from_finally_to_try; // expected-error {{cannot jump from this goto statement to its label}} expected-warning {{jump out of __finally block has undefined behavior}} 553 } 554 } 555 556 void nested() { 557 // These are not permitted. 558 __try { 559 __try { 560 } __finally { 561 goto outer_except; // expected-error {{cannot jump from this goto statement to its label}} 562 } 563 } __except(0) { // expected-note {{jump bypasses initialization of __except bloc}} 564 outer_except: 565 ; 566 } 567 568 __try { 569 __try{ 570 } __except(0) { 571 goto outer_finally; // expected-error {{cannot jump from this goto statement to its label}} 572 } 573 } __finally { // expected-note {{jump bypasses initialization of __finally bloc}} 574 outer_finally: 575 ; 576 } 577 578 // These are permitted. 579 __try { 580 __try { 581 } __finally { 582 goto after_outer_except; // expected-warning {{jump out of __finally block has undefined behavior}} 583 } 584 } __except(0) { 585 } 586 after_outer_except: 587 ; 588 589 __try { 590 __try{ 591 } __except(0) { 592 goto after_outer_finally; 593 } 594 } __finally { 595 } 596 after_outer_finally: 597 ; 598 } 599 600 // This section is academic, as MSVC doesn't support indirect gotos. 601 602 void indirect_jumps(void **ip) { 603 static void *ips[] = { &&l }; 604 605 __try { // expected-note {{jump exits __try block}} 606 // FIXME: Should this be allowed? Jumping out of the guarded section of a 607 // __try/__except doesn't require unwinding. 608 goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}} 609 } __except(0) { 610 } 611 612 __try { 613 } __except(0) { // expected-note {{jump exits __except block}} 614 // FIXME: What about here? 615 goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}} 616 } 617 618 __try { // expected-note {{jump exits __try block}} 619 goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}} 620 } __finally { 621 } 622 623 __try { 624 } __finally { // expected-note {{jump exits __finally block}} 625 goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}} 626 } 627 l: // expected-note 4 {{possible target of indirect goto statement}} 628 ; 629 } 630 631 } // namespace seh 632 633 void continue_scope_check() { 634 // These are OK. 635 for (; ({break; true;});) {} 636 for (; ({continue; true;});) {} 637 for (; int n = ({break; 0;});) {} 638 for (; int n = 0; ({break;})) {} 639 for (; int n = 0; ({continue;})) {} 640 641 // This would jump past the initialization of 'n' to the increment (where 'n' 642 // is in scope). 643 for (; int n = ({continue; 0;});) {} // expected-error {{cannot jump from this continue statement to the loop increment; jump bypasses initialization of loop condition variable}} 644 645 // An intervening loop makes it OK again. 646 for (; int n = ({while (true) continue; 0;});) {} 647 } 648