comparison gcc/testsuite/gcc.dg/Warray-bounds-48.c @ 145:1830386684a0

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