| // RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s -Wno-unreachable-code |
| // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=gnu++11 %s -Wno-unreachable-code |
| |
| namespace test0 { |
| struct D { ~D(); }; |
| |
| int f(bool b) { |
| if (b) { |
| D d; |
| goto end; |
| } |
| |
| end: |
| return 1; |
| } |
| } |
| |
| namespace test1 { |
| struct C { C(); }; |
| |
| int f(bool b) { |
| if (b) |
| goto foo; // expected-error {{goto into protected scope}} |
| C c; // expected-note {{jump bypasses variable initialization}} |
| foo: |
| return 1; |
| } |
| } |
| |
| namespace test2 { |
| struct C { C(); }; |
| |
| int f(void **ip) { |
| static void *ips[] = { &&lbl1, &&lbl2 }; |
| |
| C c; |
| goto *ip; |
| lbl1: |
| return 0; |
| lbl2: |
| return 1; |
| } |
| } |
| |
| namespace test3 { |
| struct C { C(); }; |
| |
| int f(void **ip) { |
| static void *ips[] = { &&lbl1, &&lbl2 }; |
| |
| goto *ip; |
| lbl1: { |
| C c; |
| return 0; |
| } |
| lbl2: |
| return 1; |
| } |
| } |
| |
| namespace test4 { |
| struct C { C(); }; |
| struct D { ~D(); }; |
| |
| int f(void **ip) { |
| static void *ips[] = { &&lbl1, &&lbl2 }; |
| |
| C c0; |
| |
| goto *ip; // expected-error {{indirect goto might cross protected scopes}} |
| C c1; // expected-note {{jump bypasses variable initialization}} |
| lbl1: // expected-note {{possible target of indirect goto}} |
| return 0; |
| lbl2: |
| return 1; |
| } |
| } |
| |
| namespace test5 { |
| struct C { C(); }; |
| struct D { ~D(); }; |
| |
| int f(void **ip) { |
| static void *ips[] = { &&lbl1, &&lbl2 }; |
| C c0; |
| |
| goto *ip; |
| lbl1: // expected-note {{possible target of indirect goto}} |
| return 0; |
| lbl2: |
| if (ip[1]) { |
| D d; // expected-note {{jump exits scope of variable with non-trivial destructor}} |
| ip += 2; |
| goto *ip; // expected-error {{indirect goto might cross protected scopes}} |
| } |
| return 1; |
| } |
| } |
| |
| namespace test6 { |
| struct C { C(); }; |
| |
| unsigned f(unsigned s0, unsigned s1, void **ip) { |
| static void *ips[] = { &&lbl1, &&lbl2, &&lbl3, &&lbl4 }; |
| C c0; |
| |
| goto *ip; |
| lbl1: |
| s0++; |
| goto *++ip; |
| lbl2: |
| s0 -= s1; |
| goto *++ip; |
| lbl3: { |
| unsigned tmp = s0; |
| s0 = s1; |
| s1 = tmp; |
| goto *++ip; |
| } |
| lbl4: |
| return s0; |
| } |
| } |
| |
| // C++0x says it's okay to skip non-trivial initializers on static |
| // locals, and we implement that in '03 as well. |
| namespace test7 { |
| struct C { C(); }; |
| |
| void test() { |
| goto foo; |
| static C c; |
| foo: |
| return; |
| } |
| } |
| |
| // PR7789 |
| namespace test8 { |
| void test1(int c) { |
| switch (c) { |
| case 0: |
| int x = 56; // expected-note {{jump bypasses variable initialization}} |
| case 1: // expected-error {{switch case is in protected scope}} |
| x = 10; |
| } |
| } |
| |
| void test2() { |
| goto l2; // expected-error {{goto into protected scope}} |
| l1: int x = 5; // expected-note {{jump bypasses variable initialization}} |
| l2: x++; |
| } |
| } |
| |
| namespace test9 { |
| struct S { int i; }; |
| void test1() { |
| goto foo; |
| S s; |
| foo: |
| return; |
| } |
| unsigned test2(unsigned x, unsigned y) { |
| switch (x) { |
| case 2: |
| S s; |
| if (y > 42) return x + y; |
| default: |
| return x - 2; |
| } |
| } |
| } |
| |
| // http://llvm.org/PR10462 |
| namespace PR10462 { |
| enum MyEnum { |
| something_valid, |
| something_invalid |
| }; |
| |
| bool recurse() { |
| MyEnum K; |
| switch (K) { // expected-warning {{enumeration value 'something_invalid' not handled in switch}} |
| case something_valid: |
| case what_am_i_thinking: // expected-error {{use of undeclared identifier}} |
| int *X = 0; |
| if (recurse()) { |
| } |
| |
| break; |
| } |
| } |
| |
| |
| namespace test10 { |
|
|
| int test() {
|
| static void *ps[] = { &&a0 };
|
| goto *&&a0; // expected-error {{goto into protected scope}}
|
| int a = 3; // expected-note {{jump bypasses variable initialization}}
|
| a0:
|
| return 0;
|
| } |
| |
| } |
| |
| } |
| |