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.
fn()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
f(bool b)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
f(bool b)33 int f(bool b) {
34 if (b)
35 goto foo; // expected-error {{cannot jump}}
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
f(void ** ip)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
f(void ** ip)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
f(void ** ip)77 int f(void **ip) {
78 static void *ips[] = { &&lbl1, &&lbl2 };
79
80 C c0;
81
82 goto *ip; // expected-error {{cannot jump}}
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
f(void ** ip)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 {{cannot jump}}
107 }
108 return 1;
109 }
110 }
111
112 namespace test6 {
113 struct C { C(); };
114
f(unsigned s0,unsigned s1,void ** ip)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
test()142 void test() {
143 goto foo;
144 static C c;
145 foo:
146 return;
147 }
148 }
149
150 // PR7789
151 namespace test8 {
test1(int c)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 {{cannot jump}}
157 x = 10;
158 }
159 }
160
test2()161 void test2() {
162 goto l2; // expected-error {{cannot jump}}
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; };
test1()170 void test1() {
171 goto foo;
172 S s;
173 foo:
174 return;
175 }
test2(unsigned x,unsigned y)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
recurse()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 {
test()209 int test() {
210 static void *ps[] = { &&a0 };
211 goto *&&a0; // expected-error {{cannot jump}}
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 };
f(void ** ip)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 {{cannot jump}}
229 }
230 }
231
232 namespace test12 {
233 struct C {
234 C(int x);
235 ~C();
236 };
f(void ** ip)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 {{cannot jump}}
244 }
245 }
246
247 namespace test13 {
248 struct C {
249 C(int x);
250 ~C();
251 int i;
252 };
f(void ** ip)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 {{cannot jump}}
258 }
259 }
260
261 namespace test14 {
262 struct C {
263 C(int x);
264 ~C();
265 operator int&() const;
266 };
f(void ** ip)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 {
f1()278 void f1() try {
279 goto x; // expected-error {{cannot jump}}
280 } catch(...) { // expected-note {{jump bypasses initialization of catch block}}
281 x: ;
282 }
f2()283 void f2() try { // expected-note {{jump bypasses initialization of try block}}
284 x: ;
285 } catch(...) {
286 goto x; // expected-error {{cannot jump}}
287 }
288 }
289
290 namespace test16 {
291 struct S { int n; };
f()292 int f() {
293 goto x; // expected-error {{cannot jump}}
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; };
f()302 int f() {
303 goto x; // expected-error {{cannot jump}}
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; };
f()313 int f() {
314 void *p = &&x;
315 const A a = A();
316 x:
317 B b = { 0, a }; // ok
318 goto *p;
319 }
g()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 {{cannot jump}}
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
f()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 {{cannot jump}}
346 }
347 }
348
349 namespace test20 {
350 struct A { ~A(); };
351 struct B {
352 const A &a;
353 };
354
f()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 }
g()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 {{cannot jump}}
374 }
375 }
376 #endif
377
378 namespace test21 {
f()379 template<typename T> void f() {
380 goto x; // expected-error {{cannot jump}}
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>
foo(const Source & SF,MyCl<TT * > Source::* m)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
getKind() const418 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
test(nexist,int c)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 {{cannot jump}}
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 {{cannot jump}}
440 x = 10;
441 }
442 }
443 }
444