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()20 int test3() {
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()44 int test6() {
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            L3: 4; });
70 
71   goto L4; // expected-error {{cannot jump from this goto statement to its label}}
72   {
73     int A[x],  // expected-note {{jump bypasses initialization of variable length array}}
74         B[x];  // expected-note {{jump bypasses initialization of variable length array}}
75   L4: ;
76   }
77 
78   {
79   L5: ;// ok
80     int A[x], B = ({ if (x)
81                        goto L5;
82                      else
83                        goto L6;
84                    4; });
85   L6:; // ok.
86     if (x) goto L6; // ok
87   }
88 
89   {
90   L7: ;// ok
91     int A[x], B = ({ if (x)
92                        goto L7;
93                      else
94                        goto L8;  // expected-error {{cannot jump from this goto statement to its label}}
95                      4; }),
96         C[x];   // expected-note {{jump bypasses initialization of variable length array}}
97   L8:; // bad
98   }
99 
100   {
101   L9: ;// ok
102     int A[({ if (x)
103                goto L9;
104              else
105                // FIXME:
106                goto L10;  // fixme-error {{cannot jump from this goto statement to its label}}
107            4; })];
108   L10:; // bad
109   }
110 
111   {
112     // FIXME: Crashes goto checker.
113     //goto L11;// ok
114     //int A[({   L11: 4; })];
115   }
116 
117   {
118     goto L12;
119 
120     int y = 4;   // fixme-warn: skips initializer.
121   L12:
122     ;
123   }
124 
125   // Statement expressions 2.
126   goto L1;     // expected-error {{cannot jump from this goto statement to its label}}
127   return x == ({
128                  int a[x];   // expected-note {{jump bypasses initialization of variable length array}}
129                L1:
130                  42; });
131 }
132 
test9(int n,void * P)133 void test9(int n, void *P) {
134   int Y;
135   int Z = 4;
136   goto *P;  // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}}
137 
138 L2: ;
139   int a[n]; // expected-note {{jump bypasses initialization of variable length array}}
140 
141 L3:         // expected-note {{possible target of indirect goto}}
142 L4:
143   goto *P;
144   goto L3;  // ok
145   goto L4;  // ok
146 
147   void *Ptrs[] = {
148     &&L2,
149     &&L3
150   };
151 }
152 
test10(int n,void * P)153 void test10(int n, void *P) {
154   goto L0;     // expected-error {{cannot jump from this goto statement to its label}}
155   typedef int A[n];  // expected-note {{jump bypasses initialization of VLA typedef}}
156 L0:
157 
158   goto L1;      // expected-error {{cannot jump from this goto statement to its label}}
159   A b, c[10];        // expected-note 2 {{jump bypasses initialization of variable length array}}
160 L1:
161   goto L2;     // expected-error {{cannot jump from this goto statement to its label}}
162   A d[n];      // expected-note {{jump bypasses initialization of variable length array}}
163 L2:
164   return;
165 }
166 
test11(int n)167 void test11(int n) {
168   void *P = ^{
169     switch (n) {
170     case 1:;
171     case 2:
172     case 3:;
173       int Arr[n]; // expected-note {{jump bypasses initialization of variable length array}}
174     case 4:       // expected-error {{cannot jump from switch statement to this case label}}
175       return;
176     }
177   };
178 }
179 
180 
181 // TODO: When and if gotos are allowed in blocks, this should work.
test12(int n)182 void test12(int n) {
183   void *P = ^{
184     goto L1;
185   L1:
186     goto L2;
187   L2:
188     goto L3;    // expected-error {{cannot jump from this goto statement to its label}}
189     int Arr[n]; // expected-note {{jump bypasses initialization of variable length array}}
190   L3:
191     goto L4;
192   L4: return;
193   };
194 }
195 
test13(int n,void * p)196 void test13(int n, void *p) {
197   int vla[n];
198   goto *p;
199  a0: ;
200   static void *ps[] = { &&a0 };
201 }
202 
test14(int n)203 int test14(int n) {
204   static void *ps[] = { &&a0, &&a1 };
205   if (n < 0)
206     goto *&&a0;
207 
208   if (n > 0) {
209     int vla[n];
210    a1:
211     vla[n-1] = 0;
212   }
213  a0:
214   return 0;
215 }
216 
217 
218 // PR8473: IR gen can't deal with indirect gotos past VLA
219 // initialization, so that really needs to be a hard error.
test15(int n,void * pc)220 void test15(int n, void *pc) {
221   static const void *addrs[] = { &&L1, &&L2 };
222 
223   goto *pc; // expected-error {{cannot jump from this indirect goto statement to one of its possible targets}}
224 
225  L1:
226   {
227     char vla[n]; // expected-note {{jump bypasses initialization}}
228    L2: // expected-note {{possible target}}
229     vla[0] = 'a';
230   }
231 }
232 
233 // rdar://9024687
234 int test16(int [sizeof &&z]); // expected-error {{use of address-of-label extension outside of a function body}}
235