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