xref: /llvm-project/clang/test/CXX/dcl/dcl.init/aggr.cpp (revision dcf92a249233cab103f848dd12e96e0d642a8899)
1 // RUN:  %clang_cc1 -std=c++2c -verify %s
2 
3 namespace ex1 {
4 struct C {
5   union {
6     int a;
7     const char* p;
8   };
9   int x;
10 };
11 
12 constexpr C c = { .a = 1, .x = 3 };
13 static_assert(c.a == 1);
14 static_assert(c.x == 3);
15 
16 static constexpr C c2 = { .a = 1.0, .x = 3 };
17 // expected-error@-1 {{type 'double' cannot be narrowed to 'int' in initializer list}}
18 //   expected-note@-2 {{insert an explicit cast to silence this issue}}
19 } // namespace ex1
20 
21 namespace ex2 {
22 struct A {
23   int x;
24   struct B {
25     int i;
26     int j;
27   } b;
28 };
29 
30 constexpr A a = { 1, { 2, 3 } };
31 static_assert(a.x == 1);
32 static_assert(a.b.i == 2);
33 static_assert(a.b.j == 3);
34 
35 struct base1 { int b1, b2 = 42; };
36 struct base2 {
base2ex2::base237   constexpr base2() {
38     b3 = 43;
39   }
40   int b3;
41 };
42 struct derived : base1, base2 {
43   int d;
44 };
45 
46 constexpr derived d1{{1, 2}, {}, 4};
47 static_assert(d1.b1 == 1);
48 static_assert(d1.b2 == 2);
49 static_assert(d1.b3 == 43);
50 static_assert(d1.d == 4);
51 
52 constexpr derived d2{{}, {}, 4};
53 static_assert(d2.b1 == 0);
54 static_assert(d2.b2 == 42);
55 static_assert(d2.b3 == 43);
56 static_assert(d2.d == 4);
57 } // namespace ex2
58 
59 namespace ex3 {
60 struct S {
61   int a;
62   const char* b;
63   int c;
64   int d = b[a];
65 };
66 
67 constexpr S ss = { 1, "asdf" };
68 static_assert(ss.a == 1);
69 static_assert(__builtin_strcmp(ss.b, "asdf") == 0);
70 static_assert(ss.c == int{});
71 static_assert(ss.d == ss.b[ss.a]);
72 
73 struct string {
74   int d = 43;
75 };
76 
77 struct A {
78   string a;
79   int b = 42;
80   int c = -1;
81 };
82 
83 constexpr A a{.c = 21};
84 static_assert(a.a.d == string{}.d);
85 static_assert(a.b == 42);
86 static_assert(a.c == 21);
87 } // namespace ex3
88 
89 namespace ex4 {
90 int x[] = { 1, 3, 5 };
91 static_assert(sizeof(x) / sizeof(int) == 3);
92 } // namespace ex4
93 
94 namespace ex5 {
95 struct X { int i, j, k; };
96 
97 constexpr X a[] = { 1, 2, 3, 4, 5, 6 };
98 constexpr X b[2] = { { 1, 2, 3 }, { 4, 5, 6 } };
99 static_assert(sizeof(a) == sizeof(b));
100 static_assert(a[0].i == b[0].i);
101 static_assert(a[0].j == b[0].j);
102 static_assert(a[0].k == b[0].k);
103 static_assert(a[1].i == b[1].i);
104 static_assert(a[1].j == b[1].j);
105 static_assert(a[1].k == b[1].k);
106 } // namespace ex5
107 
108 namespace ex6 {
109 struct S {
110   int y[] = { 0 };
111   // expected-error@-1 {{array bound cannot be deduced from a default member initializer}}
112 };
113 } // namespace ex6
114 
115 namespace ex7 {
116 struct A {
117   int i;
118   static int s;
119   int j;
120   int :17;
121   int k;
122 };
123 
124 constexpr A a = { 1, 2, 3 };
125 static_assert(a.i == 1);
126 static_assert(a.j == 2);
127 static_assert(a.k == 3);
128 } // namespace ex7
129 
130 namespace ex8 {
131 struct A;
132 extern A a;
133 struct A {
134   const A& a1 { A{a,a} };
135   const A& a2 { A{} };
136   // expected-error@-1 {{default member initializer for 'a2' needed within definition of enclosing class 'A' outside of member functions}}
137   //   expected-note@-2 {{default member initializer declared here}}
138 };
139 A a{a,a};
140 
141 struct B {
142   int n = B{}.n;
143   // expected-error@-1 {{default member initializer for 'n' needed within definition of enclosing class 'B' outside of member functions}}
144   //   expected-note@-2 {{default member initializer declared here}}
145 };
146 } // namespace ex8
147 
148 namespace ex9 {
149 constexpr int x[2][2] = { 3, 1, 4, 2 };
150 static_assert(x[0][0] == 3);
151 static_assert(x[0][1] == 1);
152 static_assert(x[1][0] == 4);
153 static_assert(x[1][1] == 2);
154 
155 constexpr float y[4][3] = {
156   { 1 }, { 2 }, { 3 }, { 4 }
157 };
158 static_assert(y[0][0] == 1);
159 static_assert(y[0][1] == 0);
160 static_assert(y[0][2] == 0);
161 static_assert(y[1][0] == 2);
162 static_assert(y[1][1] == 0);
163 static_assert(y[1][2] == 0);
164 static_assert(y[2][0] == 3);
165 static_assert(y[2][1] == 0);
166 static_assert(y[2][2] == 0);
167 static_assert(y[3][0] == 4);
168 static_assert(y[3][1] == 0);
169 static_assert(y[3][2] == 0);
170 } // namespace ex9
171 
172 namespace ex10 {
173 struct S1 { int a, b; };
174 struct S2 { S1 s, t; };
175 
176 constexpr S2 x[2] = { 1, 2, 3, 4, 5, 6, 7, 8 };
177 constexpr S2 y[2] = {
178   {
179     { 1, 2 },
180     { 3, 4 }
181   },
182   {
183     { 5, 6 },
184     { 7, 8 }
185   }
186 };
187 static_assert(x[0].s.a == 1);
188 static_assert(x[0].s.b == 2);
189 static_assert(x[0].t.a == 3);
190 static_assert(x[0].t.b == 4);
191 static_assert(x[1].s.a == 5);
192 static_assert(x[1].s.b == 6);
193 static_assert(x[1].t.a == 7);
194 static_assert(x[1].t.b == 8);
195 } // namespace ex10
196 
197 namespace ex11 {
198 char cv[4] = { 'a', 's', 'd', 'f', 0 };
199 // expected-error@-1 {{excess elements in array initializer}}
200 } // namespace ex11
201 
202 namespace ex12 {
203 constexpr float y[4][3] = {
204   { 1, 3, 5 },
205   { 2, 4, 6 },
206   { 3, 5, 7 },
207 };
208 static_assert(y[0][0] == 1);
209 static_assert(y[0][1] == 3);
210 static_assert(y[0][2] == 5);
211 static_assert(y[1][0] == 2);
212 static_assert(y[1][1] == 4);
213 static_assert(y[1][2] == 6);
214 static_assert(y[2][0] == 3);
215 static_assert(y[2][1] == 5);
216 static_assert(y[2][2] == 7);
217 static_assert(y[3][0] == 0.0);
218 static_assert(y[3][1] == 0.0);
219 static_assert(y[3][2] == 0.0);
220 
221 constexpr float z[4][3] = {
222   1, 3, 5, 2, 4, 6, 3, 5, 7
223 };
224 static_assert(z[0][0] == 1);
225 static_assert(z[0][1] == 3);
226 static_assert(z[0][2] == 5);
227 static_assert(z[1][0] == 2);
228 static_assert(z[1][1] == 4);
229 static_assert(z[1][2] == 6);
230 static_assert(z[2][0] == 3);
231 static_assert(z[2][1] == 5);
232 static_assert(z[2][2] == 7);
233 static_assert(z[3][0] == 0.0);
234 static_assert(z[3][1] == 0.0);
235 static_assert(z[3][2] == 0.0);
236 } // namespace ex12
237 
238 namespace ex13 {
239 struct S { } s;
240 struct A {
241   S s1;
242   int i1;
243   S s2;
244   int i2;
245   S s3;
246   int i3;
247 } a = {
248   { },              // Required initialization
249   0,
250   s,                // Required initialization
251   0
252 };                  // Initialization not required for A​::​s3 because A​::​i3 is also not initialized
253 } // namespace ex13
254 
255 namespace ex14 {
256 struct A {
257   int i;
operator intex14::A258   constexpr operator int() const { return 42; };
259 };
260 struct B {
261   A a1, a2;
262   int z;
263 };
264 constexpr A a{};
265 constexpr B b = { 4, a, a };
266 static_assert(b.a1.i == 4);
267 static_assert(b.a2.i == a.i);
268 static_assert(b.z == a.operator int());
269 } // namespace ex14
270 
271 namespace ex15 {
272 union u { // #ex15-u
273   int a;
274   const char* b;
275 };
276 
277 u a = { 1 };
278 u b = a;
279 u c = 1;
280 // expected-error@-1 {{no viable conversion from 'int' to 'u'}}
281 //   expected-note@#ex15-u {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const u &' for 1st argument}}
282 //   expected-note@#ex15-u {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'u &&' for 1st argument}}
283 u d = { 0, "asdf" };
284 // expected-error@-1 {{excess elements in union initializer}}
285 u e = { "asdf" };
286 // expected-error@-1 {{cannot initialize a member subobject of type 'int' with an lvalue of type 'const char[5]'}}
287 u f = { .b = "asdf" };
288 u g = {
289   .a = 1, // #ex15-g-a
290   .b = "asdf"
291   // expected-error@-1 {{initializer partially overrides prior initialization of this subobject}}
292   //   expected-note@#ex15-g-a {{previous initialization is here}}
293 };
294 } // namespace ex15
295