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