]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
Update copyright years.
[thirdparty/gcc.git] / gcc / testsuite / gcc.dg / Warray-bounds-48-novec.c
1 /* PR middle-end/91647 - missing -Warray-bounds accessing a zero-length array
2 of a declared object
3 { dg-do "compile" }
4 { dg-options "-O2 -Wall -fno-tree-vectorize" }
5 { dg-require-effective-target alloca } */
6
7 typedef __INT16_TYPE__ int16_t;
8 typedef __INT32_TYPE__ int32_t;
9
10 void sink (void*);
11
12 /* Exercise a true flexible member. */
13
14 struct AX
15 {
16 int32_t n;
17 int16_t ax[]; // { dg-message "while referencing 'ax'" "member" }
18 };
19
20 static void warn_ax_local (struct AX *p)
21 {
22 p->ax[0] = 0; // { dg-warning "\\\[-Warray-bounds" }
23 p->ax[1] = 1; // { dg-warning "\\\[-Warray-bounds" }
24 }
25
26 static void nowarn_ax_extern (struct AX *p)
27 {
28 p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
29 }
30
31 static void warn_ax_local_buf (struct AX *p)
32 {
33 p->ax[0] = 4; p->ax[1] = 5;
34
35 p->ax[2] = 6; // { dg-warning "\\\[-Warray-bounds" }
36 p->ax[3] = 7; // { dg-warning "\\\[-Warray-bounds" }
37 p->ax[4] = 8; // { dg-warning "\\\[-Warray-bounds" }
38 }
39
40 static void warn_ax_extern_buf (struct AX *p)
41 {
42 p->ax[0] = 9; p->ax[1] = 10; p->ax[2] = 11;
43
44 p->ax[3] = 12; // { dg-warning "\\\[-Warray-bounds" }
45 p->ax[4] = 13; // { dg-warning "\\\[-Warray-bounds" }
46 p->ax[5] = 14; // { dg-warning "\\\[-Warray-bounds" }
47 }
48
49 static void nowarn_ax_extern_bufx (struct AX *p)
50 {
51 p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
52 }
53
54 static void nowarn_ax_ref (struct AX *p)
55 {
56 p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
57 }
58
59 void test_ax (struct AX *p, unsigned n)
60 {
61 {
62 struct AX sax; // { dg-message "defined here" "struct definition" }
63 warn_ax_local (&sax);
64 sink (&sax);
65 }
66
67 {
68 extern
69 struct AX xsax;
70 nowarn_ax_extern (&xsax);
71 sink (&xsax);
72 }
73
74 {
75 /* Verify out-of-bounds access to the local BUF is diagnosed. */
76 char ax_buf_p2[sizeof (struct AX) + 2 * sizeof (int16_t)];
77 warn_ax_local_buf ((struct AX*) ax_buf_p2);
78 sink (ax_buf_p2);
79 }
80
81 {
82 /* Verify out-of-bounds access to the extern BUF with a known
83 bound is diagnosed. */
84 extern char ax_buf_p3[sizeof (struct AX) + 3 * sizeof (int16_t)];
85 warn_ax_extern_buf ((struct AX*) ax_buf_p3);
86 sink (ax_buf_p3);
87 }
88
89 {
90 /* Verify that accesses to BUFX with an unknown bound are not
91 diagnosed. */
92 extern char bufx[];
93 nowarn_ax_extern_bufx ((struct AX*) bufx);
94 sink (bufx);
95 }
96
97 {
98 /* Verify that accesses to BUFN with a runtime bound are not
99 diagnosed. */
100 char bufn[n];
101 nowarn_ax_extern_bufx ((struct AX*) bufn);
102 sink (bufn);
103 }
104
105 nowarn_ax_ref (p);
106 }
107
108
109 /* Exercise a zero-length trailing member array. It's the same as above
110 except that extern declarations with no definitions are considered to
111 have zero elements (they can't be initialized to have any). */
112
113 struct A0
114 {
115 int32_t n;
116 int16_t a0[0]; // { dg-message "while referencing 'a0'" "member" }
117 };
118
119 static void warn_a0_local (struct A0 *p)
120 {
121 p->a0[0] = 0; // { dg-warning "\\\[-Warray-bounds" }
122 p->a0[1] = 1; // { dg-warning "\\\[-Warray-bounds" }
123 }
124
125 static void warn_a0_extern (struct A0 *p)
126 {
127 p->a0[0] = 2; // { dg-warning "\\\[-Warray-bounds" }
128 p->a0[1] = 3; // { dg-warning "\\\[-Warray-bounds" }
129 }
130
131 static void warn_a0_local_buf (struct A0 *p)
132 {
133 p->a0[0] = 4; p->a0[1] = 5;
134
135 p->a0[2] = 6; // { dg-warning "\\\[-Warray-bounds" }
136 p->a0[3] = 7; // { dg-warning "\\\[-Warray-bounds" }
137 p->a0[4] = 8; // { dg-warning "\\\[-Warray-bounds" }
138 }
139
140 static void warn_a0_extern_buf (struct A0 *p)
141 {
142 p->a0[0] = 9; p->a0[1] = 10; p->a0[2] = 11;
143
144 p->a0[3] = 12; // { dg-warning "\\\[-Warray-bounds" }
145 p->a0[4] = 13; // { dg-warning "\\\[-Warray-bounds" }
146 p->a0[5] = 14; // { dg-warning "\\\[-Warray-bounds" }
147 }
148
149 static void nowarn_a0_extern_bufx (struct A0 *p)
150 {
151 p->a0[0] = 0; p->a0[99] = 99; p->a0[999] = 999; p->a0[9999] = 9999;
152 }
153
154 static void nowarn_a0_ref (struct A0 *p)
155 {
156 p->a0[0] = 0; p->a0[99] = 99; p->a0[999] = 999; p->a0[9999] = 9999;
157 }
158
159 void test_a0 (struct A0 *p, unsigned n)
160 {
161 {
162 struct A0 sa0; // { dg-message "defined here" "struct definition" }
163 warn_a0_local (&sa0);
164 sink (&sa0);
165 }
166
167 {
168 extern
169 struct A0 xsa0; // { dg-message "defined here" "struct definition" }
170 warn_a0_extern (&xsa0);
171 sink (&xsa0);
172 }
173
174 {
175 /* Verify out-of-bounds access to the local BUF is diagnosed. */
176 char a0_buf_p2[sizeof (struct A0) + 2 * sizeof (int16_t)];
177 warn_a0_local_buf ((struct A0*) a0_buf_p2);
178 sink (a0_buf_p2);
179 }
180
181 {
182 /* Verify out-of-bounds access to the extern BUF with a known
183 bound is diagnosed. */
184 extern char a0_buf_p3[sizeof (struct A0) + 3 * sizeof (int16_t)];
185 warn_a0_extern_buf ((struct A0*) a0_buf_p3);
186 sink (a0_buf_p3);
187 }
188
189 {
190 /* Verify that accesses to BUFX with an unknown bound are not
191 diagnosed. */
192 extern char bufx[];
193 nowarn_a0_extern_bufx ((struct A0*) bufx);
194 sink (bufx);
195 }
196
197 {
198 /* Verify that accesses to BUFN with a runtime bound are not
199 diagnosed. */
200 char bufn[n];
201 nowarn_a0_extern_bufx ((struct A0*) bufn);
202 sink (bufn);
203 }
204
205 nowarn_a0_ref (p);
206 }
207
208
209 /* Exercise a one-element trailing member array. It's the same as above
210 except that it has exactly one element. */
211
212 struct A1
213 {
214 int32_t n;
215 int16_t a1[1]; // { dg-message "while referencing 'a1'" }
216 };
217
218 static void warn_a1_local_noinit (struct A1 *p)
219 {
220 p->a1[0] = 0;
221 p->a1[1] = 1; // { dg-warning "\\\[-Warray-bounds" }
222 p->a1[2] = 2; // { dg-warning "\\\[-Warray-bounds" }
223 }
224
225 static void warn_a1_extern (struct A1 *p)
226 {
227 p->a1[0] = 0;
228 p->a1[1] = 1; // { dg-warning "\\\[-Warray-bounds" }
229 p->a1[2] = 2; // { dg-warning "\\\[-Warray-bounds" }
230 }
231
232 static void warn_a1_init (struct A1 *p)
233 {
234 p->a1[0] = 0;
235 p->a1[1] = 1; // { dg-warning "\\\[-Warray-bounds" }
236 p->a1[2] = 2; // { dg-warning "\\\[-Warray-bounds" }
237 }
238
239 static void warn_a1_local_buf (struct A1 *p)
240 {
241 p->a1[0] = 0; p->a1[1] = 1; p->a1[2] = 2; p->a1[3] = 3;
242
243 p->a1[4] = 4; // { dg-warning "\\\[-Warray-bounds" }
244 }
245
246 static void warn_a1_extern_buf (struct A1 *p)
247 {
248 p->a1[0] = 0; p->a1[1] = 1; p->a1[2] = 2; p->a1[3] = 3; p->a1[4] = 4;
249
250 p->a1[5] = 5; // { dg-warning "\\\[-Warray-bounds" }
251 }
252
253 static void nowarn_a1_extern_bufx (struct A1 *p)
254 {
255 p->a1[0] = 0; p->a1[99] = 99; p->a1[999] = 999; p->a1[9999] = 9999;
256 }
257
258 static void nowarn_a1_ref (struct A1 *p)
259 {
260 p->a1[0] = 0; p->a1[99] = 99; p->a1[999] = 999; p->a1[9999] = 9999;
261 }
262
263 void test_a1 (struct A1 *p, unsigned n)
264 {
265 {
266 struct A1 a1;
267 warn_a1_local_noinit (&a1);
268 sink (&a1);
269 }
270
271 {
272 extern struct A1 a1x;
273 warn_a1_extern (&a1x);
274 sink (&a1x);
275 }
276 {
277 struct A1 a1 = { 0, { 1 } };
278 warn_a1_init (&a1);
279 sink (&a1);
280 }
281
282 {
283 /* Verify out-of-bounds access to the local BUF is diagnosed. */
284 char buf_p2[sizeof (struct A1) + 2 * sizeof (int16_t)];
285 warn_a1_local_buf ((struct A1*) buf_p2);
286 sink (buf_p2);
287 }
288
289 {
290 /* Verify out-of-bounds access to the extern BUF with a known
291 bound is diagnosed. */
292 extern char a1_buf_p3[sizeof (struct A1) + 3 * sizeof (int16_t)];
293 warn_a1_extern_buf ((struct A1*) a1_buf_p3);
294 sink (a1_buf_p3);
295 }
296
297 {
298 /* Verify that accesses to BUFX with an unknown bound are not
299 diagnosed. */
300 extern char bufx[];
301 nowarn_a1_extern_bufx ((struct A1*) bufx);
302 sink (bufx);
303 }
304
305 {
306 /* Verify that accesses to BUFN with a runtime bound are not
307 diagnosed. */
308 char bufn[n];
309 nowarn_a1_extern_bufx ((struct A1*) bufn);
310 sink (bufn);
311 }
312
313 nowarn_a1_ref (p);
314 }
315
316
317 /* Exercise a two-element trailing member array. It's treated
318 the same as an interior array member. */
319
320 struct A2
321 {
322 int32_t n;
323 int16_t a2[2]; // { dg-message "while referencing 'a2'" }
324 };
325
326 static void warn_a2_noinit (struct A2 *p)
327 {
328 p->a2[0] = 0; p->a2[1] = 1;
329
330 p->a2[2] = 2; // { dg-warning "\\\[-Warray-bounds" }
331 }
332
333 static void warn_a2_init (struct A2 *p)
334 {
335 p->a2[0] = 0; p->a2[1] = 1;
336
337 p->a2[2] = 2; // { dg-warning "\\\[-Warray-bounds" }
338 p->a2[9] = 9; // { dg-warning "\\\[-Warray-bounds" }
339 }
340
341 static void warn_a2_ref (struct A2 *p)
342 {
343 p->a2[0] = 0; p->a2[1] = 1;
344
345 p->a2[2] = 2; // { dg-warning "\\\[-Warray-bounds" }
346 p->a2[9] = 9; // { dg-warning "\\\[-Warray-bounds" }
347 }
348
349 void test_a2 (struct A2 *p)
350 {
351 {
352 struct A2 a2;
353 warn_a2_noinit (&a2);
354 sink (&a2);
355 }
356
357 {
358 struct A2 a2 = { 0, { 1, 2 } };
359 warn_a2_init (&a2);
360 sink (&a2);
361 }
362
363 warn_a2_ref (p);
364 }