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) { // expected-warning {{enumeration value 'something_invalid' not handled in switch}} 197 case something_valid: 198 case what_am_i_thinking: // expected-error {{use of undeclared identifier}} 199 int *X = 0; 200 if (recurse()) { 201 } 202 203 break; 204 } 205 } 206 } 207 208 namespace test10 { 209 int test() { 210 static void *ps[] = { &&a0 }; 211 goto *&&a0; // expected-error {{cannot jump}} 212 int a = 3; // expected-note {{jump bypasses variable initialization}} 213 a0: 214 return 0; 215 } 216 } 217 218 // pr13812 219 namespace test11 { 220 struct C { 221 C(int x); 222 ~C(); 223 }; 224 void f(void **ip) { 225 static void *ips[] = { &&l0 }; 226 l0: // expected-note {{possible target of indirect goto}} 227 C c0 = 42; // expected-note {{jump exits scope of variable with non-trivial destructor}} 228 goto *ip; // expected-error {{cannot jump}} 229 } 230 } 231 232 namespace test12 { 233 struct C { 234 C(int x); 235 ~C(); 236 }; 237 void f(void **ip) { 238 static void *ips[] = { &&l0 }; 239 const C c0 = 17; 240 l0: // expected-note {{possible target of indirect goto}} 241 const C &c1 = 42; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}} 242 const C &c2 = c0; 243 goto *ip; // expected-error {{cannot jump}} 244 } 245 } 246 247 namespace test13 { 248 struct C { 249 C(int x); 250 ~C(); 251 int i; 252 }; 253 void f(void **ip) { 254 static void *ips[] = { &&l0 }; 255 l0: // expected-note {{possible target of indirect goto}} 256 const int &c1 = C(1).i; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}} 257 goto *ip; // expected-error {{cannot jump}} 258 } 259 } 260 261 namespace test14 { 262 struct C { 263 C(int x); 264 ~C(); 265 operator int&() const; 266 }; 267 void f(void **ip) { 268 static void *ips[] = { &&l0 }; 269 l0: 270 // no warning since the C temporary is destructed before the goto. 271 const int &c1 = C(1); 272 goto *ip; 273 } 274 } 275 276 // PR14225 277 namespace test15 { 278 void f1() try { 279 goto x; // expected-error {{cannot jump}} 280 } catch(...) { // expected-note {{jump bypasses initialization of catch block}} 281 x: ; 282 } 283 void f2() try { // expected-note {{jump bypasses initialization of try block}} 284 x: ; 285 } catch(...) { 286 goto x; // expected-error {{cannot jump}} 287 } 288 } 289 290 namespace test16 { 291 struct S { int n; }; 292 int f() { 293 goto x; // expected-error {{cannot jump}} 294 const S &s = S(); // expected-note {{jump bypasses variable initialization}} 295 x: return s.n; 296 } 297 } 298 299 #if __cplusplus >= 201103L 300 namespace test17 { 301 struct S { int get(); private: int n; }; 302 int f() { 303 goto x; // expected-error {{cannot jump}} 304 S s = {}; // expected-note {{jump bypasses variable initialization}} 305 x: return s.get(); 306 } 307 } 308 #endif 309 310 namespace test18 { 311 struct A { ~A(); }; 312 struct B { const int &r; const A &a; }; 313 int f() { 314 void *p = &&x; 315 const A a = A(); 316 x: 317 B b = { 0, a }; // ok 318 goto *p; 319 } 320 int g() { 321 void *p = &&x; 322 x: // expected-note {{possible target of indirect goto}} 323 B b = { 0, A() }; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}} 324 goto *p; // expected-error {{cannot jump}} 325 } 326 } 327 328 #if __cplusplus >= 201103L 329 namespace std { 330 typedef decltype(sizeof(int)) size_t; 331 template<typename T> struct initializer_list { 332 const T *begin; 333 size_t size; 334 initializer_list(const T *, size_t); 335 }; 336 } 337 namespace test19 { 338 struct A { ~A(); }; 339 340 int f() { 341 void *p = &&x; 342 A a; 343 x: // expected-note {{possible target of indirect goto}} 344 std::initializer_list<A> il = { a }; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}} 345 goto *p; // expected-error {{cannot jump}} 346 } 347 } 348 349 namespace test20 { 350 struct A { ~A(); }; 351 struct B { 352 const A &a; 353 }; 354 355 int f() { 356 void *p = &&x; 357 A a; 358 x: 359 std::initializer_list<B> il = { 360 a, 361 a 362 }; 363 goto *p; 364 } 365 int g() { 366 void *p = &&x; 367 A a; 368 x: // expected-note {{possible target of indirect goto}} 369 std::initializer_list<B> il = { 370 a, 371 { A() } // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}} 372 }; 373 goto *p; // expected-error {{cannot jump}} 374 } 375 } 376 #endif 377 378 namespace test21 { 379 template<typename T> void f() { 380 goto x; // expected-error {{cannot jump}} 381 T t; // expected-note {{bypasses}} 382 x: return; 383 } 384 385 template void f<int>(); 386 struct X { ~X(); }; 387 template void f<X>(); // expected-note {{instantiation of}} 388 } 389 390 namespace PR18217 { 391 typedef int *X; 392 393 template <typename T> 394 class MyCl { 395 T mem; 396 }; 397 398 class Source { 399 MyCl<X> m; 400 public: 401 int getKind() const; 402 }; 403 404 bool b; 405 template<typename TT> 406 static void foo(const Source &SF, MyCl<TT *> Source::*m) { 407 switch (SF.getKind()) { 408 case 1: return; 409 case 2: break; 410 case 3: 411 case 4: return; 412 }; 413 if (b) { 414 auto &y = const_cast<MyCl<TT *> &>(SF.*m); // expected-warning 0-1{{extension}} 415 } 416 } 417 418 int Source::getKind() const { 419 foo(*this, &Source::m); 420 return 0; 421 } 422 } 423 424 namespace test_recovery { 425 // Test that jump scope checking recovers when there are unspecified errors 426 // in the function declaration or body. 427 428 void test(nexist, int c) { // expected-error {{}} 429 nexist_fn(); // expected-error {{}} 430 goto nexist_label; // expected-error {{use of undeclared label}} 431 goto a0; // expected-error {{cannot jump}} 432 int a = 0; // expected-note {{jump bypasses variable initialization}} 433 a0:; 434 435 switch (c) { 436 case $: // expected-error {{}} 437 case 0: 438 int x = 56; // expected-note {{jump bypasses variable initialization}} 439 case 1: // expected-error {{cannot jump}} 440 x = 10; 441 } 442 } 443 } 444 445 namespace seh { 446 447 // Jumping into SEH try blocks is not permitted. 448 449 void jump_into_except() { 450 goto into_try_except_try; // expected-error {{cannot jump from this goto statement to its label}} 451 __try { // expected-note {{jump bypasses initialization of __try block}} 452 into_try_except_try: 453 ; 454 } __except(0) { 455 } 456 457 goto into_try_except_except; // expected-error {{cannot jump from this goto statement to its label}} 458 __try { 459 } __except(0) { // expected-note {{jump bypasses initialization of __except block}} 460 into_try_except_except: 461 ; 462 } 463 } 464 465 void jump_into_finally() { 466 goto into_try_except_try; // expected-error {{cannot jump from this goto statement to its label}} 467 __try { // expected-note {{jump bypasses initialization of __try block}} 468 into_try_except_try: 469 ; 470 } __finally { 471 } 472 473 goto into_try_except_finally; // expected-error {{cannot jump from this goto statement to its label}} 474 __try { 475 } __finally { // expected-note {{jump bypasses initialization of __finally block}} 476 into_try_except_finally: 477 ; 478 } 479 } 480 481 // Jumping out of SEH try blocks ok in general. (Jumping out of a __finally 482 // has undefined behavior.) 483 484 void jump_out_of_except() { 485 __try { 486 goto out_of_except_try; 487 } __except(0) { 488 } 489 out_of_except_try: 490 ; 491 492 __try { 493 } __except(0) { 494 goto out_of_except_except; 495 } 496 out_of_except_except: 497 ; 498 } 499 500 void jump_out_of_finally() { 501 __try { 502 goto out_of_finally_try; 503 } __finally { 504 } 505 out_of_finally_try: 506 ; 507 508 __try { 509 } __finally { 510 goto out_of_finally_finally; // expected-warning {{jump out of __finally block has undefined behavior}} 511 } 512 513 __try { 514 } __finally { 515 goto *&&out_of_finally_finally; // expected-warning {{jump out of __finally block has undefined behavior}} 516 } 517 out_of_finally_finally: 518 ; 519 } 520 521 // Jumping between protected scope and handler is not permitted. 522 523 void jump_try_except() { 524 __try { 525 goto from_try_to_except; // expected-error {{cannot jump from this goto statement to its label}} 526 } __except(0) { // expected-note {{jump bypasses initialization of __except block}} 527 from_try_to_except: 528 ; 529 } 530 531 __try { // expected-note {{jump bypasses initialization of __try block}} 532 from_except_to_try: 533 ; 534 } __except(0) { 535 goto from_except_to_try; // expected-error {{cannot jump from this goto statement to its label}} 536 } 537 } 538 539 void jump_try_finally() { 540 __try { 541 goto from_try_to_finally; // expected-error {{cannot jump from this goto statement to its label}} 542 } __finally { // expected-note {{jump bypasses initialization of __finally block}} 543 from_try_to_finally: 544 ; 545 } 546 547 __try { // expected-note {{jump bypasses initialization of __try block}} 548 from_finally_to_try: 549 ; 550 } __finally { 551 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}} 552 } 553 } 554 555 void nested() { 556 // These are not permitted. 557 __try { 558 __try { 559 } __finally { 560 goto outer_except; // expected-error {{cannot jump from this goto statement to its label}} 561 } 562 } __except(0) { // expected-note {{jump bypasses initialization of __except bloc}} 563 outer_except: 564 ; 565 } 566 567 __try { 568 __try{ 569 } __except(0) { 570 goto outer_finally; // expected-error {{cannot jump from this goto statement to its label}} 571 } 572 } __finally { // expected-note {{jump bypasses initialization of __finally bloc}} 573 outer_finally: 574 ; 575 } 576 577 // These are permitted. 578 __try { 579 __try { 580 } __finally { 581 goto after_outer_except; // expected-warning {{jump out of __finally block has undefined behavior}} 582 } 583 } __except(0) { 584 } 585 after_outer_except: 586 ; 587 588 __try { 589 __try{ 590 } __except(0) { 591 goto after_outer_finally; 592 } 593 } __finally { 594 } 595 after_outer_finally: 596 ; 597 } 598 599 // This section is academic, as MSVC doesn't support indirect gotos. 600 601 void indirect_jumps(void **ip) { 602 static void *ips[] = { &&l }; 603 604 __try { // expected-note {{jump exits __try block}} 605 // FIXME: Should this be allowed? Jumping out of the guarded section of a 606 // __try/__except doesn't require unwinding. 607 goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}} 608 } __except(0) { 609 } 610 611 __try { 612 } __except(0) { // expected-note {{jump exits __except block}} 613 // FIXME: What about here? 614 goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}} 615 } 616 617 __try { // expected-note {{jump exits __try block}} 618 goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}} 619 } __finally { 620 } 621 622 __try { 623 } __finally { // expected-note {{jump exits __finally block}} 624 goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}} 625 } 626 l: // expected-note 4 {{possible target of indirect goto statement}} 627 ; 628 } 629 630 } // namespace seh 631