xref: /minix3/external/bsd/llvm/dist/clang/test/SemaCXX/scope-check.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -fcxx-exceptions %s -Wno-unreachable-code
2*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -fcxx-exceptions -std=gnu++11 %s -Wno-unreachable-code
3*f4a2713aSLionel Sambuc 
4*f4a2713aSLionel Sambuc namespace test0 {
5*f4a2713aSLionel Sambuc   struct D { ~D(); };
6*f4a2713aSLionel Sambuc 
7*f4a2713aSLionel Sambuc   int f(bool b) {
8*f4a2713aSLionel Sambuc     if (b) {
9*f4a2713aSLionel Sambuc       D d;
10*f4a2713aSLionel Sambuc       goto end;
11*f4a2713aSLionel Sambuc     }
12*f4a2713aSLionel Sambuc 
13*f4a2713aSLionel Sambuc   end:
14*f4a2713aSLionel Sambuc     return 1;
15*f4a2713aSLionel Sambuc   }
16*f4a2713aSLionel Sambuc }
17*f4a2713aSLionel Sambuc 
18*f4a2713aSLionel Sambuc namespace test1 {
19*f4a2713aSLionel Sambuc   struct C { C(); };
20*f4a2713aSLionel Sambuc 
21*f4a2713aSLionel Sambuc   int f(bool b) {
22*f4a2713aSLionel Sambuc     if (b)
23*f4a2713aSLionel Sambuc       goto foo; // expected-error {{goto into protected scope}}
24*f4a2713aSLionel Sambuc     C c; // expected-note {{jump bypasses variable initialization}}
25*f4a2713aSLionel Sambuc   foo:
26*f4a2713aSLionel Sambuc     return 1;
27*f4a2713aSLionel Sambuc   }
28*f4a2713aSLionel Sambuc }
29*f4a2713aSLionel Sambuc 
30*f4a2713aSLionel Sambuc namespace test2 {
31*f4a2713aSLionel Sambuc   struct C { C(); };
32*f4a2713aSLionel Sambuc 
33*f4a2713aSLionel Sambuc   int f(void **ip) {
34*f4a2713aSLionel Sambuc     static void *ips[] = { &&lbl1, &&lbl2 };
35*f4a2713aSLionel Sambuc 
36*f4a2713aSLionel Sambuc     C c;
37*f4a2713aSLionel Sambuc     goto *ip;
38*f4a2713aSLionel Sambuc   lbl1:
39*f4a2713aSLionel Sambuc     return 0;
40*f4a2713aSLionel Sambuc   lbl2:
41*f4a2713aSLionel Sambuc     return 1;
42*f4a2713aSLionel Sambuc   }
43*f4a2713aSLionel Sambuc }
44*f4a2713aSLionel Sambuc 
45*f4a2713aSLionel Sambuc namespace test3 {
46*f4a2713aSLionel Sambuc   struct C { C(); };
47*f4a2713aSLionel Sambuc 
48*f4a2713aSLionel Sambuc   int f(void **ip) {
49*f4a2713aSLionel Sambuc     static void *ips[] = { &&lbl1, &&lbl2 };
50*f4a2713aSLionel Sambuc 
51*f4a2713aSLionel Sambuc     goto *ip;
52*f4a2713aSLionel Sambuc   lbl1: {
53*f4a2713aSLionel Sambuc     C c;
54*f4a2713aSLionel Sambuc     return 0;
55*f4a2713aSLionel Sambuc   }
56*f4a2713aSLionel Sambuc   lbl2:
57*f4a2713aSLionel Sambuc     return 1;
58*f4a2713aSLionel Sambuc   }
59*f4a2713aSLionel Sambuc }
60*f4a2713aSLionel Sambuc 
61*f4a2713aSLionel Sambuc namespace test4 {
62*f4a2713aSLionel Sambuc   struct C { C(); };
63*f4a2713aSLionel Sambuc   struct D { ~D(); };
64*f4a2713aSLionel Sambuc 
65*f4a2713aSLionel Sambuc   int f(void **ip) {
66*f4a2713aSLionel Sambuc     static void *ips[] = { &&lbl1, &&lbl2 };
67*f4a2713aSLionel Sambuc 
68*f4a2713aSLionel Sambuc     C c0;
69*f4a2713aSLionel Sambuc 
70*f4a2713aSLionel Sambuc     goto *ip; // expected-error {{indirect goto might cross protected scopes}}
71*f4a2713aSLionel Sambuc     C c1; // expected-note {{jump bypasses variable initialization}}
72*f4a2713aSLionel Sambuc   lbl1: // expected-note {{possible target of indirect goto}}
73*f4a2713aSLionel Sambuc     return 0;
74*f4a2713aSLionel Sambuc   lbl2:
75*f4a2713aSLionel Sambuc     return 1;
76*f4a2713aSLionel Sambuc   }
77*f4a2713aSLionel Sambuc }
78*f4a2713aSLionel Sambuc 
79*f4a2713aSLionel Sambuc namespace test5 {
80*f4a2713aSLionel Sambuc   struct C { C(); };
81*f4a2713aSLionel Sambuc   struct D { ~D(); };
82*f4a2713aSLionel Sambuc 
83*f4a2713aSLionel Sambuc   int f(void **ip) {
84*f4a2713aSLionel Sambuc     static void *ips[] = { &&lbl1, &&lbl2 };
85*f4a2713aSLionel Sambuc     C c0;
86*f4a2713aSLionel Sambuc 
87*f4a2713aSLionel Sambuc     goto *ip;
88*f4a2713aSLionel Sambuc   lbl1: // expected-note {{possible target of indirect goto}}
89*f4a2713aSLionel Sambuc     return 0;
90*f4a2713aSLionel Sambuc   lbl2:
91*f4a2713aSLionel Sambuc     if (ip[1]) {
92*f4a2713aSLionel Sambuc       D d; // expected-note {{jump exits scope of variable with non-trivial destructor}}
93*f4a2713aSLionel Sambuc       ip += 2;
94*f4a2713aSLionel Sambuc       goto *ip; // expected-error {{indirect goto might cross protected scopes}}
95*f4a2713aSLionel Sambuc     }
96*f4a2713aSLionel Sambuc     return 1;
97*f4a2713aSLionel Sambuc   }
98*f4a2713aSLionel Sambuc }
99*f4a2713aSLionel Sambuc 
100*f4a2713aSLionel Sambuc namespace test6 {
101*f4a2713aSLionel Sambuc   struct C { C(); };
102*f4a2713aSLionel Sambuc 
103*f4a2713aSLionel Sambuc   unsigned f(unsigned s0, unsigned s1, void **ip) {
104*f4a2713aSLionel Sambuc     static void *ips[] = { &&lbl1, &&lbl2, &&lbl3, &&lbl4 };
105*f4a2713aSLionel Sambuc     C c0;
106*f4a2713aSLionel Sambuc 
107*f4a2713aSLionel Sambuc     goto *ip;
108*f4a2713aSLionel Sambuc   lbl1:
109*f4a2713aSLionel Sambuc     s0++;
110*f4a2713aSLionel Sambuc     goto *++ip;
111*f4a2713aSLionel Sambuc   lbl2:
112*f4a2713aSLionel Sambuc     s0 -= s1;
113*f4a2713aSLionel Sambuc     goto *++ip;
114*f4a2713aSLionel Sambuc   lbl3: {
115*f4a2713aSLionel Sambuc     unsigned tmp = s0;
116*f4a2713aSLionel Sambuc     s0 = s1;
117*f4a2713aSLionel Sambuc     s1 = tmp;
118*f4a2713aSLionel Sambuc     goto *++ip;
119*f4a2713aSLionel Sambuc   }
120*f4a2713aSLionel Sambuc   lbl4:
121*f4a2713aSLionel Sambuc     return s0;
122*f4a2713aSLionel Sambuc   }
123*f4a2713aSLionel Sambuc }
124*f4a2713aSLionel Sambuc 
125*f4a2713aSLionel Sambuc // C++0x says it's okay to skip non-trivial initializers on static
126*f4a2713aSLionel Sambuc // locals, and we implement that in '03 as well.
127*f4a2713aSLionel Sambuc namespace test7 {
128*f4a2713aSLionel Sambuc   struct C { C(); };
129*f4a2713aSLionel Sambuc 
130*f4a2713aSLionel Sambuc   void test() {
131*f4a2713aSLionel Sambuc     goto foo;
132*f4a2713aSLionel Sambuc     static C c;
133*f4a2713aSLionel Sambuc   foo:
134*f4a2713aSLionel Sambuc     return;
135*f4a2713aSLionel Sambuc   }
136*f4a2713aSLionel Sambuc }
137*f4a2713aSLionel Sambuc 
138*f4a2713aSLionel Sambuc // PR7789
139*f4a2713aSLionel Sambuc namespace test8 {
140*f4a2713aSLionel Sambuc   void test1(int c) {
141*f4a2713aSLionel Sambuc     switch (c) {
142*f4a2713aSLionel Sambuc     case 0:
143*f4a2713aSLionel Sambuc       int x = 56; // expected-note {{jump bypasses variable initialization}}
144*f4a2713aSLionel Sambuc     case 1:       // expected-error {{switch case is in protected scope}}
145*f4a2713aSLionel Sambuc       x = 10;
146*f4a2713aSLionel Sambuc     }
147*f4a2713aSLionel Sambuc   }
148*f4a2713aSLionel Sambuc 
149*f4a2713aSLionel Sambuc   void test2() {
150*f4a2713aSLionel Sambuc     goto l2;     // expected-error {{goto into protected scope}}
151*f4a2713aSLionel Sambuc   l1: int x = 5; // expected-note {{jump bypasses variable initialization}}
152*f4a2713aSLionel Sambuc   l2: x++;
153*f4a2713aSLionel Sambuc   }
154*f4a2713aSLionel Sambuc }
155*f4a2713aSLionel Sambuc 
156*f4a2713aSLionel Sambuc namespace test9 {
157*f4a2713aSLionel Sambuc   struct S { int i; };
158*f4a2713aSLionel Sambuc   void test1() {
159*f4a2713aSLionel Sambuc     goto foo;
160*f4a2713aSLionel Sambuc     S s;
161*f4a2713aSLionel Sambuc   foo:
162*f4a2713aSLionel Sambuc     return;
163*f4a2713aSLionel Sambuc   }
164*f4a2713aSLionel Sambuc   unsigned test2(unsigned x, unsigned y) {
165*f4a2713aSLionel Sambuc     switch (x) {
166*f4a2713aSLionel Sambuc     case 2:
167*f4a2713aSLionel Sambuc       S s;
168*f4a2713aSLionel Sambuc       if (y > 42) return x + y;
169*f4a2713aSLionel Sambuc     default:
170*f4a2713aSLionel Sambuc       return x - 2;
171*f4a2713aSLionel Sambuc     }
172*f4a2713aSLionel Sambuc   }
173*f4a2713aSLionel Sambuc }
174*f4a2713aSLionel Sambuc 
175*f4a2713aSLionel Sambuc // http://llvm.org/PR10462
176*f4a2713aSLionel Sambuc namespace PR10462 {
177*f4a2713aSLionel Sambuc   enum MyEnum {
178*f4a2713aSLionel Sambuc     something_valid,
179*f4a2713aSLionel Sambuc     something_invalid
180*f4a2713aSLionel Sambuc   };
181*f4a2713aSLionel Sambuc 
182*f4a2713aSLionel Sambuc   bool recurse() {
183*f4a2713aSLionel Sambuc     MyEnum K;
184*f4a2713aSLionel Sambuc     switch (K) { // expected-warning {{enumeration value 'something_invalid' not handled in switch}}
185*f4a2713aSLionel Sambuc     case something_valid:
186*f4a2713aSLionel Sambuc     case what_am_i_thinking: // expected-error {{use of undeclared identifier}}
187*f4a2713aSLionel Sambuc       int *X = 0;
188*f4a2713aSLionel Sambuc       if (recurse()) {
189*f4a2713aSLionel Sambuc       }
190*f4a2713aSLionel Sambuc 
191*f4a2713aSLionel Sambuc       break;
192*f4a2713aSLionel Sambuc     }
193*f4a2713aSLionel Sambuc   }
194*f4a2713aSLionel Sambuc }
195*f4a2713aSLionel Sambuc 
196*f4a2713aSLionel Sambuc namespace test10 {
197*f4a2713aSLionel Sambuc   int test() {
198*f4a2713aSLionel Sambuc     static void *ps[] = { &&a0 };
199*f4a2713aSLionel Sambuc     goto *&&a0; // expected-error {{goto into protected scope}}
200*f4a2713aSLionel Sambuc     int a = 3; // expected-note {{jump bypasses variable initialization}}
201*f4a2713aSLionel Sambuc   a0:
202*f4a2713aSLionel Sambuc     return 0;
203*f4a2713aSLionel Sambuc   }
204*f4a2713aSLionel Sambuc }
205*f4a2713aSLionel Sambuc 
206*f4a2713aSLionel Sambuc // pr13812
207*f4a2713aSLionel Sambuc namespace test11 {
208*f4a2713aSLionel Sambuc   struct C {
209*f4a2713aSLionel Sambuc     C(int x);
210*f4a2713aSLionel Sambuc     ~C();
211*f4a2713aSLionel Sambuc   };
212*f4a2713aSLionel Sambuc   void f(void **ip) {
213*f4a2713aSLionel Sambuc     static void *ips[] = { &&l0 };
214*f4a2713aSLionel Sambuc   l0:  // expected-note {{possible target of indirect goto}}
215*f4a2713aSLionel Sambuc     C c0 = 42; // expected-note {{jump exits scope of variable with non-trivial destructor}}
216*f4a2713aSLionel Sambuc     goto *ip; // expected-error {{indirect goto might cross protected scopes}}
217*f4a2713aSLionel Sambuc   }
218*f4a2713aSLionel Sambuc }
219*f4a2713aSLionel Sambuc 
220*f4a2713aSLionel Sambuc namespace test12 {
221*f4a2713aSLionel Sambuc   struct C {
222*f4a2713aSLionel Sambuc     C(int x);
223*f4a2713aSLionel Sambuc     ~C();
224*f4a2713aSLionel Sambuc   };
225*f4a2713aSLionel Sambuc   void f(void **ip) {
226*f4a2713aSLionel Sambuc     static void *ips[] = { &&l0 };
227*f4a2713aSLionel Sambuc     const C c0 = 17;
228*f4a2713aSLionel Sambuc   l0: // expected-note {{possible target of indirect goto}}
229*f4a2713aSLionel Sambuc     const C &c1 = 42; // expected-note {{jump exits scope of variable with non-trivial destructor}}
230*f4a2713aSLionel Sambuc     const C &c2 = c0;
231*f4a2713aSLionel Sambuc     goto *ip; // expected-error {{indirect goto might cross protected scopes}}
232*f4a2713aSLionel Sambuc   }
233*f4a2713aSLionel Sambuc }
234*f4a2713aSLionel Sambuc 
235*f4a2713aSLionel Sambuc namespace test13 {
236*f4a2713aSLionel Sambuc   struct C {
237*f4a2713aSLionel Sambuc     C(int x);
238*f4a2713aSLionel Sambuc     ~C();
239*f4a2713aSLionel Sambuc     int i;
240*f4a2713aSLionel Sambuc   };
241*f4a2713aSLionel Sambuc   void f(void **ip) {
242*f4a2713aSLionel Sambuc     static void *ips[] = { &&l0 };
243*f4a2713aSLionel Sambuc   l0: // expected-note {{possible target of indirect goto}}
244*f4a2713aSLionel Sambuc     const int &c1 = C(1).i; // expected-note {{jump exits scope of variable with non-trivial destructor}}
245*f4a2713aSLionel Sambuc     goto *ip;  // expected-error {{indirect goto might cross protected scopes}}
246*f4a2713aSLionel Sambuc   }
247*f4a2713aSLionel Sambuc }
248*f4a2713aSLionel Sambuc 
249*f4a2713aSLionel Sambuc namespace test14 {
250*f4a2713aSLionel Sambuc   struct C {
251*f4a2713aSLionel Sambuc     C(int x);
252*f4a2713aSLionel Sambuc     ~C();
253*f4a2713aSLionel Sambuc     operator int&() const;
254*f4a2713aSLionel Sambuc   };
255*f4a2713aSLionel Sambuc   void f(void **ip) {
256*f4a2713aSLionel Sambuc     static void *ips[] = { &&l0 };
257*f4a2713aSLionel Sambuc   l0:
258*f4a2713aSLionel Sambuc     // no warning since the C temporary is destructed before the goto.
259*f4a2713aSLionel Sambuc     const int &c1 = C(1);
260*f4a2713aSLionel Sambuc     goto *ip;
261*f4a2713aSLionel Sambuc   }
262*f4a2713aSLionel Sambuc }
263*f4a2713aSLionel Sambuc 
264*f4a2713aSLionel Sambuc // PR14225
265*f4a2713aSLionel Sambuc namespace test15 {
266*f4a2713aSLionel Sambuc   void f1() try {
267*f4a2713aSLionel Sambuc     goto x; // expected-error {{goto into protected scope}}
268*f4a2713aSLionel Sambuc   } catch(...) {  // expected-note {{jump bypasses initialization of catch block}}
269*f4a2713aSLionel Sambuc     x: ;
270*f4a2713aSLionel Sambuc   }
271*f4a2713aSLionel Sambuc   void f2() try {  // expected-note {{jump bypasses initialization of try block}}
272*f4a2713aSLionel Sambuc     x: ;
273*f4a2713aSLionel Sambuc   } catch(...) {
274*f4a2713aSLionel Sambuc     goto x; // expected-error {{goto into protected scope}}
275*f4a2713aSLionel Sambuc   }
276*f4a2713aSLionel Sambuc }
277*f4a2713aSLionel Sambuc 
278*f4a2713aSLionel Sambuc namespace test16 {
279*f4a2713aSLionel Sambuc   struct S { int n; };
280*f4a2713aSLionel Sambuc   int f() {
281*f4a2713aSLionel Sambuc     goto x; // expected-error {{goto into protected scope}}
282*f4a2713aSLionel Sambuc     const S &s = S(); // expected-note {{jump bypasses variable initialization}}
283*f4a2713aSLionel Sambuc x:  return s.n;
284*f4a2713aSLionel Sambuc   }
285*f4a2713aSLionel Sambuc }
286*f4a2713aSLionel Sambuc 
287*f4a2713aSLionel Sambuc #if __cplusplus >= 201103L
288*f4a2713aSLionel Sambuc namespace test17 {
289*f4a2713aSLionel Sambuc   struct S { int get(); private: int n; };
290*f4a2713aSLionel Sambuc   int f() {
291*f4a2713aSLionel Sambuc     goto x; // expected-error {{goto into protected scope}}
292*f4a2713aSLionel Sambuc     S s = {}; // expected-note {{jump bypasses variable initialization}}
293*f4a2713aSLionel Sambuc x:  return s.get();
294*f4a2713aSLionel Sambuc   }
295*f4a2713aSLionel Sambuc }
296*f4a2713aSLionel Sambuc #endif
297*f4a2713aSLionel Sambuc 
298*f4a2713aSLionel Sambuc // This test must be last, because the error prohibits further jump diagnostics.
299*f4a2713aSLionel Sambuc namespace testInvalid {
300*f4a2713aSLionel Sambuc Invalid inv; // expected-error {{unknown type name}}
301*f4a2713aSLionel Sambuc // Make sure this doesn't assert.
302*f4a2713aSLionel Sambuc void fn()
303*f4a2713aSLionel Sambuc {
304*f4a2713aSLionel Sambuc     int c = 0;
305*f4a2713aSLionel Sambuc     if (inv)
306*f4a2713aSLionel Sambuc Here: ;
307*f4a2713aSLionel Sambuc     goto Here;
308*f4a2713aSLionel Sambuc }
309*f4a2713aSLionel Sambuc }
310