xref: /aosp_15_r20/external/clang/test/Sema/scope-check.c (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=gnu99 %s -Wno-unreachable-code
2*67e74705SXin Li 
test1(int x)3*67e74705SXin Li int test1(int x) {
4*67e74705SXin Li   goto L;    // expected-error{{cannot jump from this goto statement to its label}}
5*67e74705SXin Li   int a[x];  // expected-note {{jump bypasses initialization of variable length array}}
6*67e74705SXin Li   int b[x];  // expected-note {{jump bypasses initialization of variable length array}}
7*67e74705SXin Li   L:
8*67e74705SXin Li   return sizeof a;
9*67e74705SXin Li }
10*67e74705SXin Li 
test2(int x)11*67e74705SXin Li int test2(int x) {
12*67e74705SXin Li   goto L;            // expected-error{{cannot jump from this goto statement to its label}}
13*67e74705SXin Li   typedef int a[x];  // expected-note {{jump bypasses initialization of VLA typedef}}
14*67e74705SXin Li   L:
15*67e74705SXin Li   return sizeof(a);
16*67e74705SXin Li }
17*67e74705SXin Li 
18*67e74705SXin Li void test3clean(int*);
19*67e74705SXin Li 
test3()20*67e74705SXin Li int test3() {
21*67e74705SXin Li   goto L;            // expected-error{{cannot jump from this goto statement to its label}}
22*67e74705SXin Li int a __attribute((cleanup(test3clean))); // expected-note {{jump bypasses initialization of variable with __attribute__((cleanup))}}
23*67e74705SXin Li L:
24*67e74705SXin Li   return a;
25*67e74705SXin Li }
26*67e74705SXin Li 
test4(int x)27*67e74705SXin Li int test4(int x) {
28*67e74705SXin Li   goto L;       // expected-error{{cannot jump from this goto statement to its label}}
29*67e74705SXin Li int a[x];       // expected-note {{jump bypasses initialization of variable length array}}
30*67e74705SXin Li   test4(x);
31*67e74705SXin Li L:
32*67e74705SXin Li   return sizeof a;
33*67e74705SXin Li }
34*67e74705SXin Li 
test5(int x)35*67e74705SXin Li int test5(int x) {
36*67e74705SXin Li   int a[x];
37*67e74705SXin Li   test5(x);
38*67e74705SXin Li   goto L;  // Ok.
39*67e74705SXin Li L:
40*67e74705SXin Li   goto L;  // Ok.
41*67e74705SXin Li   return sizeof a;
42*67e74705SXin Li }
43*67e74705SXin Li 
test6()44*67e74705SXin Li int test6() {
45*67e74705SXin Li   // just plain invalid.
46*67e74705SXin Li   goto x;  // expected-error {{use of undeclared label 'x'}}
47*67e74705SXin Li }
48*67e74705SXin Li 
test7(int x)49*67e74705SXin Li void test7(int x) {
50*67e74705SXin Li   switch (x) {
51*67e74705SXin Li   case 1: ;
52*67e74705SXin Li     int a[x];       // expected-note {{jump bypasses initialization of variable length array}}
53*67e74705SXin Li   case 2:           // expected-error {{cannot jump from switch statement to this case label}}
54*67e74705SXin Li     a[1] = 2;
55*67e74705SXin Li     break;
56*67e74705SXin Li   }
57*67e74705SXin Li }
58*67e74705SXin Li 
test8(int x)59*67e74705SXin Li int test8(int x) {
60*67e74705SXin Li   // For statement.
61*67e74705SXin Li   goto L2;     // expected-error {{cannot jump from this goto statement to its label}}
62*67e74705SXin Li   for (int arr[x];   // expected-note {{jump bypasses initialization of variable length array}}
63*67e74705SXin Li        ; ++x)
64*67e74705SXin Li     L2:;
65*67e74705SXin Li 
66*67e74705SXin Li   // Statement expressions.
67*67e74705SXin Li   goto L3;   // expected-error {{cannot jump from this goto statement to its label}}
68*67e74705SXin Li   int Y = ({  int a[x];   // expected-note {{jump bypasses initialization of variable length array}}
69*67e74705SXin Li            L3: 4; });
70*67e74705SXin Li 
71*67e74705SXin Li   goto L4; // expected-error {{cannot jump from this goto statement to its label}}
72*67e74705SXin Li   {
73*67e74705SXin Li     int A[x],  // expected-note {{jump bypasses initialization of variable length array}}
74*67e74705SXin Li         B[x];  // expected-note {{jump bypasses initialization of variable length array}}
75*67e74705SXin Li   L4: ;
76*67e74705SXin Li   }
77*67e74705SXin Li 
78*67e74705SXin Li   {
79*67e74705SXin Li   L5: ;// ok
80*67e74705SXin Li     int A[x], B = ({ if (x)
81*67e74705SXin Li                        goto L5;
82*67e74705SXin Li                      else
83*67e74705SXin Li                        goto L6;
84*67e74705SXin Li                    4; });
85*67e74705SXin Li   L6:; // ok.
86*67e74705SXin Li     if (x) goto L6; // ok
87*67e74705SXin Li   }
88*67e74705SXin Li 
89*67e74705SXin Li   {
90*67e74705SXin Li   L7: ;// ok
91*67e74705SXin Li     int A[x], B = ({ if (x)
92*67e74705SXin Li                        goto L7;
93*67e74705SXin Li                      else
94*67e74705SXin Li                        goto L8;  // expected-error {{cannot jump from this goto statement to its label}}
95*67e74705SXin Li                      4; }),
96*67e74705SXin Li         C[x];   // expected-note {{jump bypasses initialization of variable length array}}
97*67e74705SXin Li   L8:; // bad
98*67e74705SXin Li   }
99*67e74705SXin Li 
100*67e74705SXin Li   {
101*67e74705SXin Li   L9: ;// ok
102*67e74705SXin Li     int A[({ if (x)
103*67e74705SXin Li                goto L9;
104*67e74705SXin Li              else
105*67e74705SXin Li                // FIXME:
106*67e74705SXin Li                goto L10;  // fixme-error {{cannot jump from this goto statement to its label}}
107*67e74705SXin Li            4; })];
108*67e74705SXin Li   L10:; // bad
109*67e74705SXin Li   }
110*67e74705SXin Li 
111*67e74705SXin Li   {
112*67e74705SXin Li     // FIXME: Crashes goto checker.
113*67e74705SXin Li     //goto L11;// ok
114*67e74705SXin Li     //int A[({   L11: 4; })];
115*67e74705SXin Li   }
116*67e74705SXin Li 
117*67e74705SXin Li   {
118*67e74705SXin Li     goto L12;
119*67e74705SXin Li 
120*67e74705SXin Li     int y = 4;   // fixme-warn: skips initializer.
121*67e74705SXin Li   L12:
122*67e74705SXin Li     ;
123*67e74705SXin Li   }
124*67e74705SXin Li 
125*67e74705SXin Li   // Statement expressions 2.
126*67e74705SXin Li   goto L1;     // expected-error {{cannot jump from this goto statement to its label}}
127*67e74705SXin Li   return x == ({
128*67e74705SXin Li                  int a[x];   // expected-note {{jump bypasses initialization of variable length array}}
129*67e74705SXin Li                L1:
130*67e74705SXin Li                  42; });
131*67e74705SXin Li }
132*67e74705SXin Li 
test9(int n,void * P)133*67e74705SXin Li void test9(int n, void *P) {
134*67e74705SXin Li   int Y;
135*67e74705SXin Li   int Z = 4;
136*67e74705SXin Li   goto *P;  // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}}
137*67e74705SXin Li 
138*67e74705SXin Li L2: ;
139*67e74705SXin Li   int a[n]; // expected-note {{jump bypasses initialization of variable length array}}
140*67e74705SXin Li 
141*67e74705SXin Li L3:         // expected-note {{possible target of indirect goto}}
142*67e74705SXin Li L4:
143*67e74705SXin Li   goto *P;
144*67e74705SXin Li   goto L3;  // ok
145*67e74705SXin Li   goto L4;  // ok
146*67e74705SXin Li 
147*67e74705SXin Li   void *Ptrs[] = {
148*67e74705SXin Li     &&L2,
149*67e74705SXin Li     &&L3
150*67e74705SXin Li   };
151*67e74705SXin Li }
152*67e74705SXin Li 
test10(int n,void * P)153*67e74705SXin Li void test10(int n, void *P) {
154*67e74705SXin Li   goto L0;     // expected-error {{cannot jump from this goto statement to its label}}
155*67e74705SXin Li   typedef int A[n];  // expected-note {{jump bypasses initialization of VLA typedef}}
156*67e74705SXin Li L0:
157*67e74705SXin Li 
158*67e74705SXin Li   goto L1;      // expected-error {{cannot jump from this goto statement to its label}}
159*67e74705SXin Li   A b, c[10];        // expected-note 2 {{jump bypasses initialization of variable length array}}
160*67e74705SXin Li L1:
161*67e74705SXin Li   goto L2;     // expected-error {{cannot jump from this goto statement to its label}}
162*67e74705SXin Li   A d[n];      // expected-note {{jump bypasses initialization of variable length array}}
163*67e74705SXin Li L2:
164*67e74705SXin Li   return;
165*67e74705SXin Li }
166*67e74705SXin Li 
test11(int n)167*67e74705SXin Li void test11(int n) {
168*67e74705SXin Li   void *P = ^{
169*67e74705SXin Li     switch (n) {
170*67e74705SXin Li     case 1:;
171*67e74705SXin Li     case 2:
172*67e74705SXin Li     case 3:;
173*67e74705SXin Li       int Arr[n]; // expected-note {{jump bypasses initialization of variable length array}}
174*67e74705SXin Li     case 4:       // expected-error {{cannot jump from switch statement to this case label}}
175*67e74705SXin Li       return;
176*67e74705SXin Li     }
177*67e74705SXin Li   };
178*67e74705SXin Li }
179*67e74705SXin Li 
180*67e74705SXin Li 
181*67e74705SXin Li // TODO: When and if gotos are allowed in blocks, this should work.
test12(int n)182*67e74705SXin Li void test12(int n) {
183*67e74705SXin Li   void *P = ^{
184*67e74705SXin Li     goto L1;
185*67e74705SXin Li   L1:
186*67e74705SXin Li     goto L2;
187*67e74705SXin Li   L2:
188*67e74705SXin Li     goto L3;    // expected-error {{cannot jump from this goto statement to its label}}
189*67e74705SXin Li     int Arr[n]; // expected-note {{jump bypasses initialization of variable length array}}
190*67e74705SXin Li   L3:
191*67e74705SXin Li     goto L4;
192*67e74705SXin Li   L4: return;
193*67e74705SXin Li   };
194*67e74705SXin Li }
195*67e74705SXin Li 
test13(int n,void * p)196*67e74705SXin Li void test13(int n, void *p) {
197*67e74705SXin Li   int vla[n];
198*67e74705SXin Li   goto *p;
199*67e74705SXin Li  a0: ;
200*67e74705SXin Li   static void *ps[] = { &&a0 };
201*67e74705SXin Li }
202*67e74705SXin Li 
test14(int n)203*67e74705SXin Li int test14(int n) {
204*67e74705SXin Li   static void *ps[] = { &&a0, &&a1 };
205*67e74705SXin Li   if (n < 0)
206*67e74705SXin Li     goto *&&a0;
207*67e74705SXin Li 
208*67e74705SXin Li   if (n > 0) {
209*67e74705SXin Li     int vla[n];
210*67e74705SXin Li    a1:
211*67e74705SXin Li     vla[n-1] = 0;
212*67e74705SXin Li   }
213*67e74705SXin Li  a0:
214*67e74705SXin Li   return 0;
215*67e74705SXin Li }
216*67e74705SXin Li 
217*67e74705SXin Li 
218*67e74705SXin Li // PR8473: IR gen can't deal with indirect gotos past VLA
219*67e74705SXin Li // initialization, so that really needs to be a hard error.
test15(int n,void * pc)220*67e74705SXin Li void test15(int n, void *pc) {
221*67e74705SXin Li   static const void *addrs[] = { &&L1, &&L2 };
222*67e74705SXin Li 
223*67e74705SXin Li   goto *pc; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}}
224*67e74705SXin Li 
225*67e74705SXin Li  L1:
226*67e74705SXin Li   {
227*67e74705SXin Li     char vla[n]; // expected-note {{jump bypasses initialization}}
228*67e74705SXin Li    L2: // expected-note {{possible target}}
229*67e74705SXin Li     vla[0] = 'a';
230*67e74705SXin Li   }
231*67e74705SXin Li }
232*67e74705SXin Li 
233*67e74705SXin Li // rdar://9024687
234*67e74705SXin Li int test16(int [sizeof &&z]); // expected-error {{use of address-of-label extension outside of a function body}}
235