111
|
1 // PR c++/42121 - g++ should warn or error on internal 0 size array in struct
|
|
2 // { dg-do compile }
|
|
3 // { dg-options "-Wno-error=pedantic" }
|
|
4
|
|
5 // Flexible array members are a feature of C99 (and newer) not provided
|
|
6 // by C++ 2014 and prior. G++ supports both the C99/C11 kind of flexible
|
|
7 // array members and pre-C99 zero-size arrays (defining an array of size
|
|
8 // zero). Since both features are provided for compatibility with C,
|
|
9 // G++ allows them in the same contexts as in C.
|
|
10
|
|
11 #include "flexary.h"
|
|
12
|
|
13 struct Sx {
|
|
14 int a[]; // { dg-error "in an otherwise empty" }
|
|
15 };
|
|
16
|
|
17 // Verify that non-data members or static data members either before
|
|
18 // or after a flexible array member in an otherwise empty struct don't
|
|
19 // suppress the diagnostic.
|
|
20 struct Sx2 {
|
|
21 int a[]; // { dg-error "in an otherwise empty" }
|
|
22 typedef int I;
|
|
23 };
|
|
24
|
|
25 struct Sx3 {
|
|
26 typedef int I;
|
|
27 int a[]; // { dg-error "in an otherwise empty" }
|
|
28 };
|
|
29
|
|
30 struct Sx4 {
|
|
31 int a[]; // { dg-error "in an otherwise empty" }
|
|
32 enum E { e };
|
|
33 };
|
|
34
|
|
35 struct Sx5 {
|
|
36 enum E { e };
|
|
37 int a[]; // { dg-error "in an otherwise empty" }
|
|
38 };
|
|
39
|
|
40 struct Sx6 {
|
|
41 int a[]; // { dg-error "in an otherwise empty" }
|
|
42 static int i;
|
|
43 };
|
|
44
|
|
45 struct Sx7 {
|
|
46 static int i;
|
|
47 int a[]; // { dg-error "in an otherwise empty" }
|
|
48 };
|
|
49
|
|
50 struct Sx8 {
|
|
51 int a[]; // { dg-error "in an otherwise empty" }
|
|
52 Sx8 () { }
|
|
53 };
|
|
54
|
|
55 struct Sx9 {
|
|
56 Sx9 () { }
|
|
57 int a[]; // { dg-error "in an otherwise empty" }
|
|
58 };
|
|
59
|
|
60 struct Sx10 {
|
|
61 int a[]; // { dg-error "in an otherwise empty" }
|
|
62 virtual ~Sx10 () { }
|
|
63 };
|
|
64
|
|
65 struct Sx11 {
|
|
66 virtual ~Sx11 () { }
|
|
67 int a[]; // { dg-error "in an otherwise empty" }
|
|
68 };
|
|
69
|
|
70 struct Sx12 {
|
|
71 int a[]; // { dg-error "in an otherwise empty" }
|
|
72 virtual void foo () = 0;
|
|
73 };
|
|
74
|
|
75 struct Sx13 {
|
|
76 virtual void foo () = 0;
|
|
77 int a[]; // { dg-error "in an otherwise empty" }
|
|
78 };
|
|
79
|
|
80 struct Sx14 {
|
|
81 int a[][1]; // { dg-error "in an otherwise empty" }
|
|
82 };
|
|
83
|
|
84 struct Sx15 {
|
|
85 typedef int A[];
|
|
86 A a; // { dg-error "in an otherwise empty" }
|
|
87 };
|
|
88
|
|
89 // Verify also that a zero-size array doesn't suppress the diagnostic.
|
|
90 struct Sx16 {
|
|
91 // a_0 below is diagnosed with -Wpedantic only and emits
|
|
92 // warning: ISO C++ forbids zero-size arrays
|
|
93 int a_0 [0];
|
|
94 int a_x []; // { dg-error "in an otherwise empty" }
|
|
95 };
|
|
96
|
|
97 struct Sx17 {
|
|
98 int a_x []; // { dg-error "flexible array member" }
|
|
99
|
|
100 // a_0 below is diagnosed with -Wpedantic only and emits
|
|
101 // warning: ISO C++ forbids zero-size arrays
|
|
102 int a_0 [0];
|
|
103 };
|
|
104
|
|
105 // An empty struct is treated as if it had a single member of type
|
|
106 // char but the member cannot be accessed. Therefore, a struct
|
|
107 // containing a flexible array member followed by an empty struct
|
|
108 // is diagnosed to prevent the former subobject from sharing space
|
|
109 // with the latter.
|
|
110 struct Sx18 {
|
|
111 int a_x []; // { dg-error "flexible array member" }
|
|
112 struct { /* empty */ } s;
|
|
113 };
|
|
114
|
|
115 // Anonymous structs are a G++ extension. Members of anonymous structs
|
|
116 // are treated as if they were declared in the enclosing class.
|
|
117 struct Sx19 {
|
|
118 struct { int i; }; // anonymous struct
|
|
119 int a_x [];
|
|
120 };
|
|
121
|
|
122 // Unlike in the case above, a named struct is not anonymous and
|
|
123 // so doesn't contribute its member to that of the enclosing struct.
|
|
124 struct Sx20 {
|
|
125 struct S { int i; };
|
|
126 int a_x []; // { dg-error "in an otherwise empty" }
|
|
127 };
|
|
128
|
|
129 struct Sx21 {
|
|
130 int a_x []; // { dg-error "not at end" }
|
|
131 struct S { } s;
|
|
132 };
|
|
133
|
|
134 struct Sx22 {
|
|
135 int a_x []; // { dg-error "not at end" }
|
|
136 union { int i; };
|
|
137 };
|
|
138
|
|
139 struct Sx23 {
|
|
140 union { int i; };
|
|
141 int a_x [];
|
|
142 };
|
|
143
|
|
144 struct Sx24 {
|
|
145 struct S;
|
|
146 S a_x []; // { dg-error "incomplete type" }
|
|
147 };
|
|
148
|
|
149 struct Sx25 {
|
|
150 struct S { };
|
|
151 S a_x []; // { dg-error "flexible array member" }
|
|
152 };
|
|
153
|
|
154 struct Sx26 {
|
|
155 struct { }
|
|
156 a_x []; // { dg-error "flexible array member" }
|
|
157 };
|
|
158
|
|
159 struct Sx27 {
|
|
160 int i;
|
|
161 struct { }
|
|
162 a_x [];
|
|
163 };
|
|
164
|
|
165 ASSERT_AT_END (Sx27, a_x);
|
|
166
|
|
167 struct Sx28 {
|
|
168 struct { }
|
|
169 a_x []; // { dg-error "not at end" }
|
|
170 int i;
|
|
171 };
|
|
172
|
|
173 struct Sx29 {
|
|
174 // Pointer to an array of unknown size.
|
|
175 int (*a_x)[];
|
|
176 };
|
|
177
|
|
178 struct Sx30 {
|
|
179 // Reference to an array of unknown size.
|
|
180 int (&a_x)[];
|
|
181 };
|
|
182
|
|
183 struct Sx31 {
|
|
184 int a []; // { dg-error "not at end" }
|
|
185 unsigned i: 1;
|
|
186 };
|
|
187
|
|
188 struct Sx32 {
|
|
189 unsigned i: 1;
|
|
190 int a [];
|
|
191 };
|
|
192
|
|
193 ASSERT_AT_END (Sx32, a);
|
|
194
|
|
195 struct Sx33 {
|
|
196 int a []; // { dg-error "otherwise empty" }
|
|
197 friend int foo ();
|
|
198 };
|
|
199
|
|
200 struct Sx34 {
|
|
201 friend int foo ();
|
|
202 int a []; // { dg-error "otherwise empty" }
|
|
203 };
|
|
204
|
|
205 // Verify that intervening non-field declarations of members other
|
|
206 // than non-static data members don't affect the diagnostics.
|
|
207 struct Sx35 {
|
|
208 int a[]; // { dg-error "not at end" }
|
|
209 typedef int I;
|
|
210 int n;
|
|
211 };
|
|
212
|
|
213 struct Sx36 {
|
|
214 int n;
|
|
215 typedef int I;
|
|
216 int a[];
|
|
217 };
|
|
218
|
|
219 ASSERT_AT_END (Sx36, a);
|
|
220
|
|
221 struct Sx37 {
|
|
222 int a[]; // { dg-error "not at end" }
|
|
223 enum E { };
|
|
224 int n;
|
|
225 };
|
|
226
|
|
227 struct Sx38 {
|
|
228 int n;
|
|
229 enum E { };
|
|
230 int a[];
|
|
231 };
|
|
232
|
|
233 ASSERT_AT_END (Sx38, a);
|
|
234
|
|
235 struct Sx39 {
|
|
236 int a[]; // { dg-error "not at end" }
|
|
237 struct S;
|
|
238 int n;
|
|
239 };
|
|
240
|
|
241 struct Sx40 {
|
|
242 int n;
|
|
243 struct S;
|
|
244 int a[];
|
|
245 };
|
|
246
|
|
247 ASSERT_AT_END (Sx40, a);
|
|
248
|
|
249 struct Sx41 {
|
|
250 int a[]; // { dg-error "not at end" }
|
|
251 static int i;
|
|
252 int n;
|
|
253 };
|
|
254
|
|
255 struct Sx42 {
|
|
256 int n;
|
|
257 static int i;
|
|
258 int a[];
|
|
259 };
|
|
260
|
|
261 ASSERT_AT_END (Sx42, a);
|
|
262
|
|
263 struct Sx43 {
|
|
264 int a[]; // { dg-error "not at end" }
|
|
265 Sx43 ();
|
|
266 int n;
|
|
267 };
|
|
268
|
|
269 struct Sx44 {
|
|
270 int n;
|
|
271 Sx44 ();
|
|
272 int a[];
|
|
273 };
|
|
274
|
|
275 ASSERT_AT_END (Sx44, a);
|
|
276
|
|
277 struct S_S_S_x {
|
|
278 struct A {
|
|
279 struct B {
|
|
280 int a[]; // { dg-error "flexible array member" }
|
|
281 } b;
|
|
282 } a;
|
|
283 };
|
|
284
|
|
285 // Since members of an anonymous struct or union are considered to be
|
|
286 // members of the enclosing union the below defintions are valid and
|
|
287 // must be accepted.
|
|
288
|
|
289 struct Anon1 {
|
|
290 int n;
|
|
291 struct {
|
|
292 int good[];
|
|
293 };
|
|
294 };
|
|
295
|
|
296 ASSERT_AT_END (Anon1, good);
|
|
297
|
|
298 struct NotAnon1 {
|
|
299 int n;
|
|
300 // The following is not an anonymous struct -- the type is unnamed
|
|
301 // but the object has a name.
|
|
302 struct {
|
|
303 int bad[]; // { dg-error "otherwise empty" }
|
|
304 } name;
|
|
305 };
|
|
306
|
|
307 struct Anon2 {
|
|
308 struct {
|
|
309 int n;
|
|
310 struct {
|
|
311 int good[];
|
|
312 };
|
|
313 };
|
|
314 };
|
|
315
|
|
316 ASSERT_AT_END (Anon2, good);
|
|
317
|
|
318 struct Anon3 {
|
|
319 struct {
|
|
320 struct {
|
|
321 int n;
|
|
322 int good[];
|
|
323 };
|
|
324 };
|
|
325 };
|
|
326
|
|
327 ASSERT_AT_END (Anon3, good);
|
|
328
|
|
329 struct Anon4 {
|
|
330 struct {
|
|
331 int in_empty_struct[]; // { dg-error "in an otherwise empty" }
|
|
332 };
|
|
333 };
|
|
334
|
|
335 struct Anon5 {
|
|
336 struct {
|
|
337 int not_at_end[]; // { dg-error "not at end" }
|
|
338 };
|
|
339 int n;
|
|
340 };
|
|
341
|
|
342 struct Anon6 {
|
|
343 struct {
|
|
344 struct {
|
|
345 int not_at_end[]; // { dg-error "not at end" }
|
|
346 };
|
|
347 int n;
|
|
348 };
|
|
349 };
|
|
350
|
|
351
|
|
352 struct Anon7 {
|
|
353 struct {
|
|
354 struct {
|
|
355 int not_at_end[]; // { dg-error "not at end" }
|
|
356 };
|
|
357 };
|
|
358 int n;
|
|
359 };
|
|
360
|
|
361 struct Six {
|
|
362 int i;
|
|
363 int a[];
|
|
364 };
|
|
365
|
|
366 ASSERT_AT_END (Six, a);
|
|
367
|
|
368 class Cx {
|
|
369 int a[]; // { dg-error "flexible array member" }
|
|
370 };
|
|
371
|
|
372 class Cix {
|
|
373 int i;
|
|
374 int a[];
|
|
375 };
|
|
376
|
|
377 struct Sxi {
|
|
378 int a[]; // { dg-error "not at end" }
|
|
379 int i;
|
|
380 };
|
|
381
|
|
382 struct S0 {
|
|
383 int a[0];
|
|
384 };
|
|
385
|
|
386 struct S0i {
|
|
387 int a[0];
|
|
388 int i;
|
|
389 };
|
|
390
|
|
391 struct S_a0_ax {
|
|
392 int a0[0];
|
|
393 int ax[]; // { dg-error "flexible array member" }
|
|
394 };
|
|
395
|
|
396 struct S_a0_i_ax {
|
|
397 int a0[0];
|
|
398 int i;
|
|
399 int ax[];
|
|
400 };
|
|
401
|
|
402 ASSERT_AT_END (S_a0_i_ax, ax);
|
|
403
|
|
404 struct Si_a0_ax {
|
|
405 int i;
|
|
406 int a0[0];
|
|
407 int ax[];
|
|
408 };
|
|
409
|
|
410 ASSERT_AT_END (Si_a0_ax, ax);
|
|
411
|
|
412 struct Si_ax_a0 {
|
|
413 int i;
|
|
414 int ax[]; // { dg-error "not at end" }
|
|
415 int a0[0];
|
|
416 };
|
|
417
|
|
418 struct S_u0_ax {
|
|
419 union { } u[0];
|
|
420 int ax[]; // { dg-error "flexible array member" }
|
|
421 };
|
|
422
|
|
423 struct S_a1_s2 {
|
|
424 int a[1];
|
|
425 int b[2];
|
|
426 };
|