Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -fcxx-exceptions %s -Wno-unreachable-code
      2 // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -fcxx-exceptions -std=gnu++11 %s -Wno-unreachable-code
      3 
      4 namespace test0 {
      5   struct D { ~D(); };
      6 
      7   int f(bool b) {
      8     if (b) {
      9       D d;
     10       goto end;
     11     }
     12 
     13   end:
     14     return 1;
     15   }
     16 }
     17 
     18 namespace test1 {
     19   struct C { C(); };
     20 
     21   int f(bool b) {
     22     if (b)
     23       goto foo; // expected-error {{goto into protected scope}}
     24     C c; // expected-note {{jump bypasses variable initialization}}
     25   foo:
     26     return 1;
     27   }
     28 }
     29 
     30 namespace test2 {
     31   struct C { C(); };
     32 
     33   int f(void **ip) {
     34     static void *ips[] = { &&lbl1, &&lbl2 };
     35 
     36     C c;
     37     goto *ip;
     38   lbl1:
     39     return 0;
     40   lbl2:
     41     return 1;
     42   }
     43 }
     44 
     45 namespace test3 {
     46   struct C { C(); };
     47 
     48   int f(void **ip) {
     49     static void *ips[] = { &&lbl1, &&lbl2 };
     50 
     51     goto *ip;
     52   lbl1: {
     53     C c;
     54     return 0;
     55   }
     56   lbl2:
     57     return 1;
     58   }
     59 }
     60 
     61 namespace test4 {
     62   struct C { C(); };
     63   struct D { ~D(); };
     64 
     65   int f(void **ip) {
     66     static void *ips[] = { &&lbl1, &&lbl2 };
     67 
     68     C c0;
     69 
     70     goto *ip; // expected-error {{indirect goto might cross protected scopes}}
     71     C c1; // expected-note {{jump bypasses variable initialization}}
     72   lbl1: // expected-note {{possible target of indirect goto}}
     73     return 0;
     74   lbl2:
     75     return 1;
     76   }
     77 }
     78 
     79 namespace test5 {
     80   struct C { C(); };
     81   struct D { ~D(); };
     82 
     83   int f(void **ip) {
     84     static void *ips[] = { &&lbl1, &&lbl2 };
     85     C c0;
     86 
     87     goto *ip;
     88   lbl1: // expected-note {{possible target of indirect goto}}
     89     return 0;
     90   lbl2:
     91     if (ip[1]) {
     92       D d; // expected-note {{jump exits scope of variable with non-trivial destructor}}
     93       ip += 2;
     94       goto *ip; // expected-error {{indirect goto might cross protected scopes}}
     95     }
     96     return 1;
     97   }
     98 }
     99 
    100 namespace test6 {
    101   struct C { C(); };
    102 
    103   unsigned f(unsigned s0, unsigned s1, void **ip) {
    104     static void *ips[] = { &&lbl1, &&lbl2, &&lbl3, &&lbl4 };
    105     C c0;
    106 
    107     goto *ip;
    108   lbl1:
    109     s0++;
    110     goto *++ip;
    111   lbl2:
    112     s0 -= s1;
    113     goto *++ip;
    114   lbl3: {
    115     unsigned tmp = s0;
    116     s0 = s1;
    117     s1 = tmp;
    118     goto *++ip;
    119   }
    120   lbl4:
    121     return s0;
    122   }
    123 }
    124 
    125 // C++0x says it's okay to skip non-trivial initializers on static
    126 // locals, and we implement that in '03 as well.
    127 namespace test7 {
    128   struct C { C(); };
    129 
    130   void test() {
    131     goto foo;
    132     static C c;
    133   foo:
    134     return;
    135   }
    136 }
    137 
    138 // PR7789
    139 namespace test8 {
    140   void test1(int c) {
    141     switch (c) {
    142     case 0:
    143       int x = 56; // expected-note {{jump bypasses variable initialization}}
    144     case 1:       // expected-error {{switch case is in protected scope}}
    145       x = 10;
    146     }
    147   }
    148 
    149   void test2() {
    150     goto l2;     // expected-error {{goto into protected scope}}
    151   l1: int x = 5; // expected-note {{jump bypasses variable initialization}}
    152   l2: x++;
    153   }
    154 }
    155 
    156 namespace test9 {
    157   struct S { int i; };
    158   void test1() {
    159     goto foo;
    160     S s;
    161   foo:
    162     return;
    163   }
    164   unsigned test2(unsigned x, unsigned y) {
    165     switch (x) {
    166     case 2:
    167       S s;
    168       if (y > 42) return x + y;
    169     default:
    170       return x - 2;
    171     }
    172   }
    173 }
    174 
    175 // http://llvm.org/PR10462
    176 namespace PR10462 {
    177   enum MyEnum {
    178     something_valid,
    179     something_invalid
    180   };
    181 
    182   bool recurse() {
    183     MyEnum K;
    184     switch (K) { // expected-warning {{enumeration value 'something_invalid' not handled in switch}}
    185     case something_valid:
    186     case what_am_i_thinking: // expected-error {{use of undeclared identifier}}
    187       int *X = 0;
    188       if (recurse()) {
    189       }
    190 
    191       break;
    192     }
    193   }
    194 }
    195 
    196 namespace test10 {
    197   int test() {
    198     static void *ps[] = { &&a0 };
    199     goto *&&a0; // expected-error {{goto into protected scope}}
    200     int a = 3; // expected-note {{jump bypasses variable initialization}}
    201   a0:
    202     return 0;
    203   }
    204 }
    205 
    206 // pr13812
    207 namespace test11 {
    208   struct C {
    209     C(int x);
    210     ~C();
    211   };
    212   void f(void **ip) {
    213     static void *ips[] = { &&l0 };
    214   l0:  // expected-note {{possible target of indirect goto}}
    215     C c0 = 42; // expected-note {{jump exits scope of variable with non-trivial destructor}}
    216     goto *ip; // expected-error {{indirect goto might cross protected scopes}}
    217   }
    218 }
    219 
    220 namespace test12 {
    221   struct C {
    222     C(int x);
    223     ~C();
    224   };
    225   void f(void **ip) {
    226     static void *ips[] = { &&l0 };
    227     const C c0 = 17;
    228   l0: // expected-note {{possible target of indirect goto}}
    229     const C &c1 = 42; // expected-note {{jump exits scope of variable with non-trivial destructor}}
    230     const C &c2 = c0;
    231     goto *ip; // expected-error {{indirect goto might cross protected scopes}}
    232   }
    233 }
    234 
    235 namespace test13 {
    236   struct C {
    237     C(int x);
    238     ~C();
    239     int i;
    240   };
    241   void f(void **ip) {
    242     static void *ips[] = { &&l0 };
    243   l0: // expected-note {{possible target of indirect goto}}
    244     const int &c1 = C(1).i; // expected-note {{jump exits scope of variable with non-trivial destructor}}
    245     goto *ip;  // expected-error {{indirect goto might cross protected scopes}}
    246   }
    247 }
    248 
    249 namespace test14 {
    250   struct C {
    251     C(int x);
    252     ~C();
    253     operator int&() const;
    254   };
    255   void f(void **ip) {
    256     static void *ips[] = { &&l0 };
    257   l0:
    258     // no warning since the C temporary is destructed before the goto.
    259     const int &c1 = C(1);
    260     goto *ip;
    261   }
    262 }
    263 
    264 // PR14225
    265 namespace test15 {
    266   void f1() try {
    267     goto x; // expected-error {{goto into protected scope}}
    268   } catch(...) {  // expected-note {{jump bypasses initialization of catch block}}
    269     x: ;
    270   }
    271   void f2() try {  // expected-note {{jump bypasses initialization of try block}}
    272     x: ;
    273   } catch(...) {
    274     goto x; // expected-error {{goto into protected scope}}
    275   }
    276 }
    277 
    278 namespace test16 {
    279 Invalid inv; // expected-error {{unknown type name}}
    280 // Make sure this doesn't assert.
    281 void fn()
    282 {
    283     int c = 0;
    284     if (inv)
    285 Here: ;
    286     goto Here;
    287 }
    288 }
    289