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 lifetime-extended temporary 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 lifetime-extended temporary 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 namespace test18 { 299 struct A { ~A(); }; 300 struct B { const int &r; const A &a; }; 301 int f() { 302 void *p = &&x; 303 const A a = A(); 304 x: 305 B b = { 0, a }; // ok 306 goto *p; 307 } 308 int g() { 309 void *p = &&x; 310 x: // expected-note {{possible target of indirect goto}} 311 B b = { 0, A() }; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}} 312 goto *p; // expected-error {{indirect goto might cross protected scopes}} 313 } 314 } 315 316 #if __cplusplus >= 201103L 317 namespace std { 318 typedef decltype(sizeof(int)) size_t; 319 template<typename T> struct initializer_list { 320 const T *begin; 321 size_t size; 322 initializer_list(const T *, size_t); 323 }; 324 } 325 namespace test19 { 326 struct A { ~A(); }; 327 328 int f() { 329 void *p = &&x; 330 A a; 331 x: // expected-note {{possible target of indirect goto}} 332 std::initializer_list<A> il = { a }; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}} 333 goto *p; // expected-error {{indirect goto might cross protected scopes}} 334 } 335 } 336 337 namespace test20 { 338 struct A { ~A(); }; 339 struct B { 340 const A &a; 341 }; 342 343 int f() { 344 void *p = &&x; 345 A a; 346 x: 347 std::initializer_list<B> il = { 348 a, 349 a 350 }; 351 goto *p; 352 } 353 int g() { 354 void *p = &&x; 355 A a; 356 x: // expected-note {{possible target of indirect goto}} 357 std::initializer_list<B> il = { 358 a, 359 { A() } // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}} 360 }; 361 goto *p; // expected-error {{indirect goto might cross protected scopes}} 362 } 363 } 364 #endif 365 366 namespace test21 { 367 template<typename T> void f() { 368 goto x; // expected-error {{protected scope}} 369 T t; // expected-note {{bypasses}} 370 x: return; 371 } 372 373 template void f<int>(); 374 struct X { ~X(); }; 375 template void f<X>(); // expected-note {{instantiation of}} 376 } 377 378 namespace PR18217 { 379 typedef int *X; 380 381 template <typename T> 382 class MyCl { 383 T mem; 384 }; 385 386 class Source { 387 MyCl<X> m; 388 public: 389 int getKind() const; 390 }; 391 392 bool b; 393 template<typename TT> 394 static void foo(const Source &SF, MyCl<TT *> Source::*m) { 395 switch (SF.getKind()) { 396 case 1: return; 397 case 2: break; 398 case 3: 399 case 4: return; 400 }; 401 if (b) { 402 auto &y = const_cast<MyCl<TT *> &>(SF.*m); // expected-warning 0-1{{extension}} 403 } 404 } 405 406 int Source::getKind() const { 407 foo(*this, &Source::m); 408 return 0; 409 } 410 } 411 412 // This test must be last, because the error prohibits further jump diagnostics. 413 namespace testInvalid { 414 Invalid inv; // expected-error {{unknown type name}} 415 // Make sure this doesn't assert. 416 void fn() 417 { 418 int c = 0; 419 if (inv) 420 Here: ; 421 goto Here; 422 } 423 } 424