1 | // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=gnu99 %s -Wno-unreachable-code |
2 | |
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 | |
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 | |
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 | |
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 | |
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 | |
44 | int test6() { |
45 | // just plain invalid. |
46 | goto x; // expected-error {{use of undeclared label 'x'}} |
47 | } |
48 | |
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 | |
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 | |
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 | |
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 | |
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. |
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 | |
196 | void test13(int n, void *p) { |
197 | int vla[n]; |
198 | goto *p; |
199 | a0: ; |
200 | static void *ps[] = { &&a0 }; |
201 | } |
202 | |
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. |
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 | |