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 struct S { int n; }; 280 int f() { 281 goto x; // expected-error {{goto into protected scope}} 282 const S &s = S(); // expected-note {{jump bypasses variable initialization}} 283 x: return s.n; 284 } 285 } 286 287 #if __cplusplus >= 201103L 288 namespace test17 { 289 struct S { int get(); private: int n; }; 290 int f() { 291 goto x; // expected-error {{goto into protected scope}} 292 S s = {}; // expected-note {{jump bypasses variable initialization}} 293 x: return s.get(); 294 } 295 } 296 #endif 297 298 // This test must be last, because the error prohibits further jump diagnostics. 299 namespace testInvalid { 300 Invalid inv; // expected-error {{unknown type name}} 301 // Make sure this doesn't assert. 302 void fn() 303 { 304 int c = 0; 305 if (inv) 306 Here: ; 307 goto Here; 308 } 309 } 310