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