]>
Commit | Line | Data |
---|---|---|
7e9a3ad3 MS |
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 | ||
a9c697b8 | 65 | ASSERT_AT_END (D5, a); // { dg-warning "'offsetof' within non-standard-layout" } |
7e9a3ad3 | 66 | |
96032047 | 67 | struct A2x_1 { |
7e9a3ad3 | 68 | size_t n; |
96032047 MS |
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." } | |
7e9a3ad3 MS |
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. | |
96032047 MS |
85 | struct D6: A2x_1, E1, A1x { }; |
86 | struct D7: E1, A2x_2, E2, A1x { }; | |
87 | struct D8: E1, E2, A2x_3, A1x { }; | |
7e9a3ad3 | 88 | |
96032047 | 89 | struct DA2x: A2x_1 { }; |
7e9a3ad3 MS |
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 | ||
a9c697b8 | 169 | ASSERT_AT_END (D22, a); // { dg-warning "'offsetof' within non-standard-layout" } |
7e9a3ad3 MS |
170 | |
171 | struct D23: E1, A5x, E2 { }; | |
172 | ||
a9c697b8 | 173 | ASSERT_AT_END (D23, a); // { dg-warning "'offsetof' within non-standard-layout" } |
7e9a3ad3 MS |
174 | |
175 | struct D24: E1, E2, A5x { }; | |
176 | ||
a9c697b8 | 177 | ASSERT_AT_END (D24, a); // { dg-warning "'offsetof' within non-standard-layout" } |
7e9a3ad3 MS |
178 | |
179 | struct DA5x: A5x { }; | |
180 | ||
181 | struct D25: DA5x, E1, E2 { }; | |
182 | ||
a9c697b8 | 183 | ASSERT_AT_END (D25, a); // { dg-warning "'offsetof' within non-standard-layout" } |
7e9a3ad3 MS |
184 | |
185 | struct D26: E1, DA5x, E2 { }; | |
186 | ||
a9c697b8 | 187 | ASSERT_AT_END (D26, a); // { dg-warning "'offsetof' within non-standard-layout" } |
7e9a3ad3 MS |
188 | |
189 | struct D27: E1, E2, DA5x { }; | |
190 | ||
a9c697b8 | 191 | ASSERT_AT_END (D27, a); // { dg-warning "'offsetof' within non-standard-layout" } |
7e9a3ad3 MS |
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 | ||
7e9a3ad3 MS |
207 | struct A7x { |
208 | size_t n; | |
96032047 | 209 | size_t a[]; // { dg-error "flexible array member .A7x::a. not at end of .struct D33." } |
7e9a3ad3 MS |
210 | }; |
211 | ||
96032047 MS |
212 | // Verify that a flexible array member in a virtual base class is not |
213 | // diagnosed. | |
7e9a3ad3 MS |
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 { }; | |
96032047 MS |
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 { }; |