1 // RUN: %clang_cc1 -triple x86_64-windows -fsyntax-only -verify -fblocks -fcxx-exceptions -fms-extensions %s -Wno-unreachable-code
2 // RUN: %clang_cc1 -triple x86_64-windows -fsyntax-only -verify -fblocks -fcxx-exceptions -fms-extensions -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) { // do not warn that 'something_invalid' is not listed;
197                  // 'what_am_i_thinking' might have been intended to be that case.
198     case something_valid:
199     case what_am_i_thinking: // expected-error {{use of undeclared identifier}}
200       int *X = 0;
201       if (recurse()) {
202       }
203 
204       break;
205     }
206   }
207 }
208 
209 namespace test10 {
test()210   int test() {
211     static void *ps[] = { &&a0 };
212     goto *&&a0; // expected-error {{cannot jump}}
213     int a = 3; // expected-note {{jump bypasses variable initialization}}
214   a0:
215     return 0;
216   }
217 }
218 
219 // pr13812
220 namespace test11 {
221   struct C {
222     C(int x);
223     ~C();
224   };
f(void ** ip)225   void f(void **ip) {
226     static void *ips[] = { &&l0 };
227   l0:  // expected-note {{possible target of indirect goto}}
228     C c0 = 42; // expected-note {{jump exits scope of variable with non-trivial destructor}}
229     goto *ip; // expected-error {{cannot jump}}
230   }
231 }
232 
233 namespace test12 {
234   struct C {
235     C(int x);
236     ~C();
237   };
f(void ** ip)238   void f(void **ip) {
239     static void *ips[] = { &&l0 };
240     const C c0 = 17;
241   l0: // expected-note {{possible target of indirect goto}}
242     const C &c1 = 42; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
243     const C &c2 = c0;
244     goto *ip; // expected-error {{cannot jump}}
245   }
246 }
247 
248 namespace test13 {
249   struct C {
250     C(int x);
251     ~C();
252     int i;
253   };
f(void ** ip)254   void f(void **ip) {
255     static void *ips[] = { &&l0 };
256   l0: // expected-note {{possible target of indirect goto}}
257     const int &c1 = C(1).i; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
258     goto *ip;  // expected-error {{cannot jump}}
259   }
260 }
261 
262 namespace test14 {
263   struct C {
264     C(int x);
265     ~C();
266     operator int&() const;
267   };
f(void ** ip)268   void f(void **ip) {
269     static void *ips[] = { &&l0 };
270   l0:
271     // no warning since the C temporary is destructed before the goto.
272     const int &c1 = C(1);
273     goto *ip;
274   }
275 }
276 
277 // PR14225
278 namespace test15 {
f1()279   void f1() try {
280     goto x; // expected-error {{cannot jump}}
281   } catch(...) {  // expected-note {{jump bypasses initialization of catch block}}
282     x: ;
283   }
f2()284   void f2() try {  // expected-note {{jump bypasses initialization of try block}}
285     x: ;
286   } catch(...) {
287     goto x; // expected-error {{cannot jump}}
288   }
289 }
290 
291 namespace test16 {
292   struct S { int n; };
f()293   int f() {
294     goto x; // expected-error {{cannot jump}}
295     const S &s = S(); // expected-note {{jump bypasses variable initialization}}
296 x:  return s.n;
297   }
298 }
299 
300 #if __cplusplus >= 201103L
301 namespace test17 {
302   struct S { int get(); private: int n; };
f()303   int f() {
304     goto x; // expected-error {{cannot jump}}
305     S s = {}; // expected-note {{jump bypasses variable initialization}}
306 x:  return s.get();
307   }
308 }
309 #endif
310 
311 namespace test18 {
312   struct A { ~A(); };
313   struct B { const int &r; const A &a; };
f()314   int f() {
315     void *p = &&x;
316     const A a = A();
317   x:
318     B b = { 0, a }; // ok
319     goto *p;
320   }
g()321   int g() {
322     void *p = &&x;
323   x: // expected-note {{possible target of indirect goto}}
324     B b = { 0, A() }; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
325     goto *p; // expected-error {{cannot jump}}
326   }
327 }
328 
329 #if __cplusplus >= 201103L
330 namespace std {
331   typedef decltype(sizeof(int)) size_t;
332   template<typename T> struct initializer_list {
333     const T *begin;
334     size_t size;
335     initializer_list(const T *, size_t);
336   };
337 }
338 namespace test19 {
339   struct A { ~A(); };
340 
f()341   int f() {
342     void *p = &&x;
343     A a;
344   x: // expected-note {{possible target of indirect goto}}
345     std::initializer_list<A> il = { a }; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
346     goto *p; // expected-error {{cannot jump}}
347   }
348 }
349 
350 namespace test20 {
351   struct A { ~A(); };
352   struct B {
353     const A &a;
354   };
355 
f()356   int f() {
357     void *p = &&x;
358     A a;
359   x:
360     std::initializer_list<B> il = {
361       a,
362       a
363     };
364     goto *p;
365   }
g()366   int g() {
367     void *p = &&x;
368     A a;
369   x: // expected-note {{possible target of indirect goto}}
370     std::initializer_list<B> il = {
371       a,
372       { A() } // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
373     };
374     goto *p; // expected-error {{cannot jump}}
375   }
376 }
377 #endif
378 
379 namespace test21 {
f()380   template<typename T> void f() {
381   goto x; // expected-error {{cannot jump}}
382     T t; // expected-note {{bypasses}}
383  x: return;
384   }
385 
386   template void f<int>();
387   struct X { ~X(); };
388   template void f<X>(); // expected-note {{instantiation of}}
389 }
390 
391 namespace PR18217 {
392   typedef int *X;
393 
394   template <typename T>
395   class MyCl {
396     T mem;
397   };
398 
399   class Source {
400     MyCl<X> m;
401   public:
402     int getKind() const;
403   };
404 
405   bool b;
406   template<typename TT>
foo(const Source & SF,MyCl<TT * > Source::* m)407   static void foo(const Source &SF, MyCl<TT *> Source::*m) {
408     switch (SF.getKind()) {
409       case 1: return;
410       case 2: break;
411       case 3:
412       case 4: return;
413     };
414     if (b) {
415       auto &y = const_cast<MyCl<TT *> &>(SF.*m); // expected-warning 0-1{{extension}}
416     }
417   }
418 
getKind() const419   int Source::getKind() const {
420     foo(*this, &Source::m);
421     return 0;
422   }
423 }
424 
425 namespace test_recovery {
426   // Test that jump scope checking recovers when there are unspecified errors
427   // in the function declaration or body.
428 
test(nexist,int c)429   void test(nexist, int c) { // expected-error {{}}
430     nexist_fn(); // expected-error {{}}
431     goto nexist_label; // expected-error {{use of undeclared label}}
432     goto a0; // expected-error {{cannot jump}}
433     int a = 0; // expected-note {{jump bypasses variable initialization}}
434     a0:;
435 
436     switch (c) {
437     case $: // expected-error {{}}
438     case 0:
439       int x = 56; // expected-note {{jump bypasses variable initialization}}
440     case 1: // expected-error {{cannot jump}}
441       x = 10;
442     }
443   }
444 }
445 
446 namespace seh {
447 
448 // Jumping into SEH try blocks is not permitted.
449 
jump_into_except()450 void jump_into_except() {
451   goto into_try_except_try; // expected-error {{cannot jump from this goto statement to its label}}
452   __try { // expected-note {{jump bypasses initialization of __try block}}
453   into_try_except_try:
454     ;
455   } __except(0) {
456   }
457 
458   goto into_try_except_except; // expected-error {{cannot jump from this goto statement to its label}}
459   __try {
460   } __except(0) { // expected-note {{jump bypasses initialization of __except block}}
461   into_try_except_except:
462     ;
463   }
464 }
465 
jump_into_finally()466 void jump_into_finally() {
467   goto into_try_except_try; // expected-error {{cannot jump from this goto statement to its label}}
468   __try { // expected-note {{jump bypasses initialization of __try block}}
469   into_try_except_try:
470     ;
471   } __finally {
472   }
473 
474   goto into_try_except_finally; // expected-error {{cannot jump from this goto statement to its label}}
475   __try {
476   } __finally { // expected-note {{jump bypasses initialization of __finally block}}
477   into_try_except_finally:
478     ;
479   }
480 }
481 
482 // Jumping out of SEH try blocks ok in general. (Jumping out of a __finally
483 // has undefined behavior.)
484 
jump_out_of_except()485 void jump_out_of_except() {
486   __try {
487     goto out_of_except_try;
488   } __except(0) {
489   }
490 out_of_except_try:
491   ;
492 
493   __try {
494   } __except(0) {
495     goto out_of_except_except;
496   }
497 out_of_except_except:
498   ;
499 }
500 
jump_out_of_finally()501 void jump_out_of_finally() {
502   __try {
503   goto out_of_finally_try;
504   } __finally {
505   }
506 out_of_finally_try:
507   ;
508 
509   __try {
510   } __finally {
511     goto out_of_finally_finally; // expected-warning {{jump out of __finally block has undefined behavior}}
512   }
513 
514   __try {
515   } __finally {
516     goto *&&out_of_finally_finally; // expected-warning {{jump out of __finally block has undefined behavior}}
517   }
518 out_of_finally_finally:
519   ;
520 }
521 
522 // Jumping between protected scope and handler is not permitted.
523 
jump_try_except()524 void jump_try_except() {
525   __try {
526     goto from_try_to_except; // expected-error {{cannot jump from this goto statement to its label}}
527   } __except(0) { // expected-note {{jump bypasses initialization of __except block}}
528   from_try_to_except:
529     ;
530   }
531 
532   __try { // expected-note {{jump bypasses initialization of __try block}}
533   from_except_to_try:
534     ;
535   } __except(0) {
536     goto from_except_to_try; // expected-error {{cannot jump from this goto statement to its label}}
537   }
538 }
539 
jump_try_finally()540 void jump_try_finally() {
541   __try {
542     goto from_try_to_finally; // expected-error {{cannot jump from this goto statement to its label}}
543   } __finally { // expected-note {{jump bypasses initialization of __finally block}}
544   from_try_to_finally:
545     ;
546   }
547 
548   __try { // expected-note {{jump bypasses initialization of __try block}}
549   from_finally_to_try:
550     ;
551   } __finally {
552     goto from_finally_to_try; // expected-error {{cannot jump from this goto statement to its label}} expected-warning {{jump out of __finally block has undefined behavior}}
553   }
554 }
555 
nested()556 void nested() {
557   // These are not permitted.
558   __try {
559     __try {
560     } __finally {
561       goto outer_except; // expected-error {{cannot jump from this goto statement to its label}}
562     }
563   } __except(0) { // expected-note {{jump bypasses initialization of __except bloc}}
564   outer_except:
565     ;
566   }
567 
568   __try {
569     __try{
570     } __except(0) {
571       goto outer_finally; // expected-error {{cannot jump from this goto statement to its label}}
572     }
573   } __finally { // expected-note {{jump bypasses initialization of __finally bloc}}
574   outer_finally:
575     ;
576   }
577 
578   // These are permitted.
579   __try {
580     __try {
581     } __finally {
582       goto after_outer_except; // expected-warning {{jump out of __finally block has undefined behavior}}
583     }
584   } __except(0) {
585   }
586 after_outer_except:
587   ;
588 
589   __try {
590     __try{
591     } __except(0) {
592       goto after_outer_finally;
593     }
594   } __finally {
595   }
596 after_outer_finally:
597   ;
598 }
599 
600 // This section is academic, as MSVC doesn't support indirect gotos.
601 
indirect_jumps(void ** ip)602 void indirect_jumps(void **ip) {
603   static void *ips[] = { &&l };
604 
605   __try { // expected-note {{jump exits __try block}}
606     // FIXME: Should this be allowed? Jumping out of the guarded section of a
607     // __try/__except doesn't require unwinding.
608     goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}}
609   } __except(0) {
610   }
611 
612   __try {
613   } __except(0) { // expected-note {{jump exits __except block}}
614     // FIXME: What about here?
615     goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}}
616   }
617 
618   __try { // expected-note {{jump exits __try block}}
619     goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}}
620   } __finally {
621   }
622 
623   __try {
624   } __finally { // expected-note {{jump exits __finally block}}
625     goto *ip; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}}
626   }
627 l: // expected-note 4 {{possible target of indirect goto statement}}
628   ;
629 }
630 
631 } // namespace seh
632