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