111
|
1 // { dg-do compile }
|
|
2 // { dg-options "-Wno-error=pedantic" }
|
|
3
|
|
4 // Test to verify flexible array members handling in base and derived
|
|
5 // classes.
|
|
6
|
|
7 #include "flexary.h"
|
|
8
|
|
9 template <class T>
|
|
10 struct S_no_diag: T {
|
|
11 char a[]; // cannot be diagnosed unless/until T is known
|
|
12 };
|
|
13
|
|
14 template <class T>
|
|
15 struct STx_1: T {
|
|
16 char a[]; // { dg-error "flexible array member" }
|
|
17 };
|
|
18
|
|
19 template <class T, int I>
|
|
20 struct STI: T {
|
|
21 char a[I]; // cannot be diagnosed unless/until T and I are known
|
|
22 };
|
|
23
|
|
24 template <class T, int I>
|
|
25 struct STIx: T {
|
|
26 char a[I];
|
|
27 };
|
|
28
|
|
29 template <int> struct E { };
|
|
30
|
|
31 STx_1<E<0> > stx_empty_1;
|
|
32 STIx<E<0>, 0> stix_empty_1;
|
|
33
|
|
34 // Verify that a sole flexible array member in a class with all empty
|
|
35 // base classes is diagnosed.
|
|
36 struct E1: E<0>, E<1> { };
|
|
37 struct E2: E<2>, E<3> { };
|
|
38 struct D1: E1, E2
|
|
39 {
|
|
40 char a[]; // { dg-error "flexible array member" }
|
|
41 };
|
|
42
|
|
43 struct NE { size_t i; };
|
|
44
|
|
45 struct A1x { int n, a[]; };
|
|
46 struct D2: A1x, E1, E2 { };
|
|
47
|
|
48 // Verify that the offset of the flexible array member is equal
|
|
49 // to the size of each of the valid structs.
|
|
50 ASSERT_AT_END (D2, a);
|
|
51
|
|
52 struct D3: E1, A1x, E2 { };
|
|
53
|
|
54 ASSERT_AT_END (D3, a);
|
|
55
|
|
56 struct D4: E1, E2, A1x { };
|
|
57
|
|
58 ASSERT_AT_END (D4, a);
|
|
59
|
|
60 // Class with non-static data members and at least one base class
|
|
61 // with such a member is not a standard layout class. The warning
|
|
62 // below is benign since GCC computes the expected value.
|
|
63 struct D5: E1, E2, NE { char a[]; };
|
|
64
|
145
|
65 ASSERT_AT_END (D5, a); // { dg-warning "'offsetof' within non-standard-layout" }
|
111
|
66
|
|
67 struct A2x_1 {
|
|
68 size_t n;
|
|
69 size_t a[]; // { dg-error "not at end of .struct D6." }
|
|
70 };
|
|
71
|
|
72 struct A2x_2 {
|
|
73 size_t n;
|
|
74 size_t a[]; // { dg-error "not at end of .struct D7." }
|
|
75 };
|
|
76
|
|
77 struct A2x_3 {
|
|
78 size_t n;
|
|
79 size_t a[]; // { dg-error "not at end of .struct D8." }
|
|
80 };
|
|
81
|
|
82 // Verify that the flexible array member in A2x above is diagnosed
|
|
83 // for each of the three struct defintions below which also derive
|
|
84 // from another struct with a flexible array member.
|
|
85 struct D6: A2x_1, E1, A1x { };
|
|
86 struct D7: E1, A2x_2, E2, A1x { };
|
|
87 struct D8: E1, E2, A2x_3, A1x { };
|
|
88
|
|
89 struct DA2x: A2x_1 { };
|
|
90
|
|
91 struct D9: DA2x, E1, E2 { };
|
|
92
|
|
93 ASSERT_AT_END (D9, a);
|
|
94
|
|
95 struct D10: E1, DA2x, E2 { };
|
|
96
|
|
97 ASSERT_AT_END (D10, a);
|
|
98
|
|
99 struct D11: E1, E2, DA2x { };
|
|
100
|
|
101 ASSERT_AT_END (D11, a);
|
|
102
|
|
103 struct A3x {
|
|
104 size_t n;
|
|
105 size_t a[]; // { dg-error "not at end of .struct D12.| D13.| D14.| D15." }
|
|
106 };
|
|
107
|
|
108 // Verify that the flexible array member in A3x above is diagnosed
|
|
109 // for each of the three struct defintions below which also derive
|
|
110 // from another struct with a non-static member.
|
|
111 struct D12: A3x, E1, NE { };
|
|
112 struct D13: E1, A3x, NE { };
|
|
113 struct D14: E1, E2, A3x, NE { };
|
|
114 struct D15: E1, E2, NE, A3x { };
|
|
115
|
|
116 struct A4x {
|
|
117 A4x ();
|
|
118 ~A4x ();
|
|
119
|
|
120 size_t n;
|
|
121 struct AS {
|
|
122 AS (int);
|
|
123 ~AS ();
|
|
124 size_t i;
|
|
125 } a[];
|
|
126 };
|
|
127
|
|
128 struct D16: A4x, E1, E2 { };
|
|
129
|
|
130 ASSERT_AT_END (D16, a);
|
|
131
|
|
132 struct D17: E1, A4x, E2 { };
|
|
133
|
|
134 ASSERT_AT_END (D17, a);
|
|
135
|
|
136 struct D18: E1, E2, A4x { };
|
|
137
|
|
138 ASSERT_AT_END (D18, a);
|
|
139
|
|
140 struct DA4x: A4x { };
|
|
141
|
|
142 struct D19: DA4x, E1, E2 { };
|
|
143
|
|
144 ASSERT_AT_END (D19, a);
|
|
145
|
|
146 struct D20: E1, DA4x, E2 { };
|
|
147
|
|
148 ASSERT_AT_END (D20, a);
|
|
149
|
|
150 struct D21: E1, E2, DA4x { };
|
|
151
|
|
152 ASSERT_AT_END (D21, a);
|
|
153
|
|
154
|
|
155 struct A5x {
|
|
156 A5x (int);
|
|
157 virtual ~A5x ();
|
|
158
|
|
159 size_t n;
|
|
160 struct AS {
|
|
161 AS (int);
|
|
162 ~AS ();
|
|
163 size_t i;
|
|
164 } a[];
|
|
165 };
|
|
166
|
|
167 struct D22: A5x, E1, E2 { };
|
|
168
|
145
|
169 ASSERT_AT_END (D22, a); // { dg-warning "'offsetof' within non-standard-layout" }
|
111
|
170
|
|
171 struct D23: E1, A5x, E2 { };
|
|
172
|
145
|
173 ASSERT_AT_END (D23, a); // { dg-warning "'offsetof' within non-standard-layout" }
|
111
|
174
|
|
175 struct D24: E1, E2, A5x { };
|
|
176
|
145
|
177 ASSERT_AT_END (D24, a); // { dg-warning "'offsetof' within non-standard-layout" }
|
111
|
178
|
|
179 struct DA5x: A5x { };
|
|
180
|
|
181 struct D25: DA5x, E1, E2 { };
|
|
182
|
145
|
183 ASSERT_AT_END (D25, a); // { dg-warning "'offsetof' within non-standard-layout" }
|
111
|
184
|
|
185 struct D26: E1, DA5x, E2 { };
|
|
186
|
145
|
187 ASSERT_AT_END (D26, a); // { dg-warning "'offsetof' within non-standard-layout" }
|
111
|
188
|
|
189 struct D27: E1, E2, DA5x { };
|
|
190
|
145
|
191 ASSERT_AT_END (D27, a); // { dg-warning "'offsetof' within non-standard-layout" }
|
111
|
192
|
|
193 // Verfify that a flexible array member is diagnosed even when deep
|
|
194 // in the base class hierarchy.
|
|
195 struct A6x {
|
|
196 size_t n;
|
|
197 size_t a[]; // { dg-error "not at end of .struct D28.| D29." }
|
|
198 };
|
|
199
|
|
200 struct AA6x: A6x { };
|
|
201 struct NE1: NE { };
|
|
202 struct NE2: NE { };
|
|
203
|
|
204 struct D28: NE1, AA6x { };
|
|
205 struct D29: AA6x, NE1 { };
|
|
206
|
|
207 struct A7x {
|
|
208 size_t n;
|
|
209 size_t a[]; // { dg-error "flexible array member .A7x::a. not at end of .struct D33." }
|
|
210 };
|
|
211
|
|
212 // Verify that a flexible array member in a virtual base class is not
|
|
213 // diagnosed.
|
|
214 struct DA7xV1: virtual A7x { };
|
|
215 struct DA7xV2: virtual A7x { };
|
|
216
|
|
217 struct D30: DA7xV1, DA7xV2 { };
|
|
218 struct D31: DA7xV1, DA7xV2 { };
|
|
219 struct D32: D30, D31 { };
|
|
220
|
|
221 // Verify the diagnostic when the flexible array is in an anonymous struct.
|
|
222 struct A8x {
|
|
223 struct { // { dg-message "next member .A8x::<unnamed struct> A8x::<anonymous>. declared here" }
|
|
224 size_t n;
|
|
225 size_t a[];
|
|
226 };
|
|
227 };
|
|
228
|
|
229 struct D33: // { dg-message "in the definition of .struct D33." }
|
|
230 A7x, A8x { };
|