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 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 {{goto into protected scope}} 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 {{indirect goto might cross protected scopes}} 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 {{indirect goto might cross protected scopes}} 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 {{switch case is in protected scope}} 157 x = 10; 158 } 159 } 160 161 void test2() { 162 goto l2; // expected-error {{goto into protected scope}} 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 {{goto into protected scope}} 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 {{indirect goto might cross protected scopes}} 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 {{indirect goto might cross protected scopes}} 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 {{indirect goto might cross protected scopes}} 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 {{goto into protected scope}} 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 {{goto into protected scope}} 287 } 288 } 289 290 namespace test16 { 291 struct S { int n; }; 292 int f() { 293 goto x; // expected-error {{goto into protected scope}} 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 {{goto into protected scope}} 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 {{indirect goto might cross protected scopes}} 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 {{indirect goto might cross protected scopes}} 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 {{indirect goto might cross protected scopes}} 374 } 375 } 376 #endif 377 378 namespace test21 { 379 template<typename T> void f() { 380 goto x; // expected-error {{protected scope}} 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 {{goto into protected scope}} 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 {{switch case is in protected scope}} 440 x = 10; 441 } 442 } 443 } 444