145
|
1 /* PR middle-end/91458 - inconsistent warning for writing past the end
|
|
2 of an array member
|
|
3 See Wstringop-overflow-3.C for the same test that exercises the other
|
|
4 warning.
|
|
5 { dg-do compile }
|
|
6 { dg-options "-O2 -Wall -Wno-stringop-overflow" }
|
|
7 { dg-skip-if "" { *-*-aix* } } */
|
|
8
|
|
9 void sink (void*);
|
|
10
|
|
11 // Exercise flexible array members.
|
|
12
|
|
13 struct Ax
|
|
14 {
|
|
15 char n;
|
|
16 char a[]; // { dg-message "while referencing .Ax::a." }
|
|
17 };
|
|
18
|
|
19 // Verify warning for a definition with no initializer.
|
|
20 Ax ax_;
|
|
21
|
|
22 void gax_ ()
|
|
23 {
|
|
24 ax_.a[0] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
25 ax_.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
26 ax_.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
27 }
|
|
28
|
|
29 // Verify warning for access to a definition with an initializer that doesn't
|
|
30 // initialize the flexible array member.
|
|
31 Ax ax0 = { 0 };
|
|
32
|
|
33 void gax0 ()
|
|
34 {
|
|
35 ax0.a[0] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
36 ax0.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
37 ax0.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
38 }
|
|
39
|
|
40 // Verify warning for access to a definition with an initializer that
|
|
41 // initializes the flexible array member to empty.
|
|
42 Ax ax0_ = { 0, { } };
|
|
43
|
|
44 void gax0_ ()
|
|
45 {
|
|
46 ax0_.a[0] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
47 ax0_.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
48 ax0_.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
49 }
|
|
50
|
|
51 // Verify warning for out-of-bounds accesses to a definition with
|
|
52 // an initializer.
|
|
53 Ax ax1 = { 1, { 0 } };
|
|
54
|
|
55 void gax1 ()
|
|
56 {
|
|
57 ax1.a[0] = 0;
|
|
58 ax1.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
59 ax1.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
60 }
|
|
61
|
|
62 Ax ax2 = { 2, { 1, 0 } };
|
|
63
|
|
64 void gax2 ()
|
|
65 {
|
|
66 ax2.a[0] = 0;
|
|
67 ax2.a[1] = 0;
|
|
68 ax2.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
69 }
|
|
70
|
|
71
|
|
72 // Verify no warning for an unknown struct object.
|
|
73 void gaxp (Ax *p)
|
|
74 {
|
|
75 p->a[0] = 0;
|
|
76 p->a[3] = 0;
|
|
77 p->a[9] = 0;
|
|
78 }
|
|
79
|
|
80
|
|
81 // Verify no warning for an extern struct object whose array may be
|
|
82 // initialized to any number of elements.
|
|
83 extern Ax axx;
|
|
84
|
|
85 void gaxx ()
|
|
86 {
|
|
87 axx.a[0] = 0;
|
|
88 axx.a[3] = 0;
|
|
89 axx.a[9] = 0;
|
|
90 }
|
|
91
|
|
92 // Exercise zero-length array members.
|
|
93
|
|
94 struct A0
|
|
95 {
|
|
96 char n;
|
|
97 char a[0]; // { dg-message "while referencing .A0::a." }
|
|
98 };
|
|
99
|
|
100 // Verify warning for a definition with no initializer.
|
|
101 A0 a0_;
|
|
102
|
|
103 void ga0_ ()
|
|
104 {
|
|
105 a0_.a[0] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
106 a0_.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
107 a0_.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
108 }
|
|
109
|
|
110 // Verify warning for access to a definition with an initializer that doesn't
|
|
111 // initialize the flexible array member.
|
|
112 A0 a00 = { 0 };
|
|
113
|
|
114 void ga00 ()
|
|
115 {
|
|
116 a00.a[0] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
117 a00.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
118 a00.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
119 }
|
|
120
|
|
121 // Verify warning for access to a definition with an initializer that
|
|
122 // initializes the flexible array member to empty.
|
|
123 A0 a00_ = { 0, { } };
|
|
124
|
|
125 void ga00_ ()
|
|
126 {
|
|
127 a00_.a[0] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
128 a00_.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
129 a00_.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
130 }
|
|
131
|
|
132 // The following are rejected with
|
|
133 // error: too many initializers for 'char [0]'
|
|
134 // A0 a01 = { 1, { 0 } };
|
|
135 // A0 a02 = { 2, { 1, 0 } };
|
|
136
|
|
137
|
|
138 // Verify no warning for an unknown struct object.
|
|
139 void ga0p (A0 *p)
|
|
140 {
|
|
141 p->a[0] = 0;
|
|
142 p->a[3] = 0;
|
|
143 p->a[9] = 0;
|
|
144 }
|
|
145
|
|
146
|
|
147 // Verify warning for an extern struct object which (unlike a true
|
|
148 // flexible array member) may not be initialized.
|
|
149 extern A0 a0x;
|
|
150
|
|
151 void ga0x ()
|
|
152 {
|
|
153 a0x.a[0] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
154 a0x.a[3] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
155 a0x.a[9] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
156 }
|
|
157
|
|
158
|
|
159 // Exercise trailing one-element array members.
|
|
160
|
|
161 struct A1
|
|
162 {
|
|
163 char n;
|
|
164 char a[1]; // { dg-message "while referencing .A1::a." }
|
|
165 };
|
|
166
|
|
167 // Verify warning for a definition with no initializer.
|
|
168 A1 a1_;
|
|
169
|
|
170 void ga1_ ()
|
|
171 {
|
|
172 a1_.a[0] = 0;
|
|
173 a1_.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
174 a1_.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
175 }
|
|
176
|
|
177 // Verify warning for access to a definition with an initializer that doesn't
|
|
178 // initialize the one-element array member.
|
|
179 A1 a1__ = { 0 };
|
|
180
|
|
181 void ga1__ ()
|
|
182 {
|
|
183 a1__.a[0] = 0;
|
|
184 a1__.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
185 a1__.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
186 }
|
|
187
|
|
188 // Verify warning for access to a definition with an initializer that
|
|
189 // initializes the one-element array member to empty.
|
|
190 A1 a1_0 = { 0, { } };
|
|
191
|
|
192 void ga1_0_ ()
|
|
193 {
|
|
194 a1_0.a[0] = 0;
|
|
195 a1_0.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
196 a1_0.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
197 }
|
|
198
|
|
199 // Verify warning for access to a definition with an initializer that
|
|
200 // initializes the one-element array member.
|
|
201 A1 a1_1 = { 0, { 1 } };
|
|
202
|
|
203 void ga1_1 ()
|
|
204 {
|
|
205 a1_1.a[0] = 0;
|
|
206 a1_1.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
207 a1_1.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
208 }
|
|
209
|
|
210
|
|
211 // Verify no warning for an unknown struct object.
|
|
212 void ga1p (A1 *p)
|
|
213 {
|
|
214 p->a[0] = 0;
|
|
215 p->a[3] = 0;
|
|
216 p->a[9] = 0;
|
|
217 }
|
|
218
|
|
219
|
|
220 // Verify warning for an extern struct object. Similar to the zero-length
|
|
221 // array case, a one-element trailing array can be initialized to at most
|
|
222 // a single element.
|
|
223 extern A1 a1x;
|
|
224
|
|
225 void ga1x ()
|
|
226 {
|
|
227 a1x.a[0] = 0;
|
|
228 a1x.a[3] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
229 a1x.a[9] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
230 }
|
|
231
|
|
232 // Exercise interior one-element array members (verify they're not
|
|
233 // treated as trailing.
|
|
234
|
|
235 struct A1i
|
|
236 {
|
|
237 char n;
|
|
238 char a[1]; // { dg-message "while referencing .A1i::a." }
|
|
239 char x;
|
|
240 };
|
|
241
|
|
242 // Verify warning for a definition with no initializer.
|
|
243 A1i a1i_;
|
|
244
|
|
245 void ga1i_ ()
|
|
246 {
|
|
247 a1i_.a[0] = 0;
|
|
248 a1i_.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
249 a1i_.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
250 }
|
|
251
|
|
252 // Verify warning for access to a definition with an initializer that doesn't
|
|
253 // initialize the one-element array member.
|
|
254 A1i a1i__ = { 0 };
|
|
255
|
|
256 void ga1i__ ()
|
|
257 {
|
|
258 a1i__.a[0] = 0;
|
|
259 a1i__.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
260 a1i__.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
261 }
|
|
262
|
|
263 // Verify warning for access to a definition with an initializer that
|
|
264 // initializes the one-element array member to empty.
|
|
265 A1 a1i_0 = { 0, { } };
|
|
266
|
|
267 void ga1i_0_ ()
|
|
268 {
|
|
269 a1i_0.a[0] = 0;
|
|
270 a1i_0.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
271 a1i_0.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
272 }
|
|
273
|
|
274 // Verify warning for access to a definition with an initializer that
|
|
275 // initializes the one-element array member.
|
|
276 A1 a1i_1 = { 0, { 1 } };
|
|
277
|
|
278 void ga1i_1 ()
|
|
279 {
|
|
280 a1i_1.a[0] = 0;
|
|
281 a1i_1.a[1] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
282 a1i_1.a[2] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
283 }
|
|
284
|
|
285
|
|
286 // Verify no warning for an unknown struct object.
|
|
287 void ga1ip (A1i *p)
|
|
288 {
|
|
289 p->a[0] = 0;
|
|
290 p->a[3] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
291 p->a[9] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
292 }
|
|
293
|
|
294
|
|
295 // Verify no warning for an extern struct object.
|
|
296 extern A1i a1ix;
|
|
297
|
|
298 void ga1ix ()
|
|
299 {
|
|
300 a1ix.a[0] = 0;
|
|
301 a1ix.a[3] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
302 a1ix.a[9] = 0; // { dg-warning "\\\[-Warray-bounds" }
|
|
303 }
|
|
304
|
|
305
|
|
306 // Verify non-POD classes with flexible array members.
|
|
307
|
|
308 struct Bx
|
|
309 {
|
|
310 char n;
|
|
311 char a[]; // { dg-message "while referencing .Bx::a." }
|
|
312
|
|
313 // Verify the warning for a constant.
|
|
314 Bx () { a[0] = 0; } // { dg-warning "\\\[-Warray-bounds" }
|
|
315
|
|
316 // And also for a non-constant. Regardless of the subscript, the array
|
|
317 // of the object in function gxi() below has a zero size.
|
|
318 Bx (int i) { a[i] = 0; } // { dg-warning "\\\[-Warray-bounds" }
|
|
319 };
|
|
320
|
|
321 void gbx (void)
|
|
322 {
|
|
323 struct Bx bx;
|
|
324 sink (&bx);
|
|
325 }
|
|
326
|
|
327 void gbxi (int i)
|
|
328 {
|
|
329 struct Bx bxi (i);
|
|
330 sink (&bxi);
|
|
331 }
|
|
332
|
|
333 struct B0
|
|
334 {
|
|
335 char n;
|
|
336 char a[0]; // { dg-message "while referencing .B0::a." }
|
|
337
|
|
338 B0 () { a[0] = 0; } // { dg-warning "\\\[-Warray-bounds" }
|
|
339 };
|
|
340
|
|
341
|
|
342 void gb0 (void)
|
|
343 {
|
|
344 struct B0 b0;
|
|
345 sink (&b0);
|
|
346 }
|
|
347
|
|
348
|
|
349 struct B1
|
|
350 {
|
|
351 char n;
|
|
352 char a[1]; // { dg-message "while referencing .B1::a." }
|
|
353
|
|
354 B1 () { a[1] = 0; } // { dg-warning "\\\[-Warray-bounds" }
|
|
355 };
|
|
356
|
|
357 void gb1 (void)
|
|
358 {
|
|
359 struct B1 b1;
|
|
360 sink (&b1);
|
|
361 }
|
|
362
|
|
363
|
|
364 struct B123
|
|
365 {
|
|
366 char a[123]; // { dg-message "while referencing .B123::a." }
|
|
367
|
|
368 B123 () { a[123] = 0; } // { dg-warning "\\\[-Warray-bounds" }
|
|
369 };
|
|
370
|
|
371 void gb123 (void)
|
|
372 {
|
|
373 struct B123 b123;
|
|
374 sink (&b123);
|
|
375 }
|
|
376
|
|
377
|
|
378 struct B234
|
|
379 {
|
|
380 char a[234]; // { dg-message "while referencing .B234::a." }
|
|
381
|
|
382 B234 (int i) { a[i] = 0; } // { dg-warning "\\\[-Warray-bounds" }
|
|
383 };
|
|
384
|
|
385 void g234 (void)
|
|
386 {
|
|
387 struct B234 b234 (234);
|
|
388 sink (&b234);
|
|
389 }
|