xref: /llvm-project/clang/test/SemaCXX/cxx2a-initializer-aggregates.cpp (revision 7df43ccf08e40468354d0564f9bcd7dfe681590b)
1 // RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,pedantic,override,reorder -pedantic-errors
2 // RUN: %clang_cc1 -std=c++17 %s -verify=expected,pedantic,override,reorder -Wno-c++20-designator -pedantic-errors
3 // RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,pedantic -Werror=c99-designator -Wno-reorder-init-list -Wno-initializer-overrides
4 // RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,reorder -Wno-c99-designator -Werror=reorder-init-list -Wno-initializer-overrides
5 // RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,override -Wno-c99-designator -Wno-reorder-init-list -Werror=initializer-overrides
6 // RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected -Wno-c99-designator -Wno-reorder-init-list -Wno-initializer-overrides
7 // RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,wmissing,wmissing-designated -Wmissing-field-initializers -Wno-c99-designator -Wno-reorder-init-list -Wno-initializer-overrides
8 // RUN: %clang_cc1 -std=c++20 %s -verify=cxx20,expected,wmissing -Wmissing-field-initializers -Wno-missing-designated-field-initializers -Wno-c99-designator -Wno-reorder-init-list -Wno-initializer-overrides
9 
10 
11 namespace class_with_ctor {
12   struct A { // cxx20-note 6{{candidate}}
13     A() = default; // cxx20-note 3{{candidate}}
14     int x;
15     int y;
16   };
17   A a = {1, 2}; // cxx20-error {{no matching constructor}}
18 
19   struct B {
20     int x;
21     int y;
22   };
23   B b1 = B(); // trigger declaration of implicit ctors
24   B b2 = {1, 2}; // ok
25 
26   struct C : A {
27     A a;
28   };
29   C c1 = {{}, {}}; // ok, call default ctor twice
30   C c2 = {{1, 2}, {3, 4}}; // cxx20-error 2{{no matching constructor}}
31 }
32 
33 namespace designator {
34 struct A { int x, y; };
35 struct B { A a; };
36 
37 A a1 = {
38   .y = 1, // reorder-note {{previous initialization for field 'y' is here}}
39   .x = 2 // reorder-error {{ISO C++ requires field designators to be specified in declaration order; field 'y' will be initialized after field 'x'}}
40 };
41 int arr[3] = {[1] = 5}; // pedantic-error {{array designators are a C99 extension}}
42 B b = {.a.x = 0}; // pedantic-error {{nested designators are a C99 extension}}
43 A a2 = {
44   .x = 1, // pedantic-error {{mixture of designated and non-designated initializers in the same initializer list is a C99 extension}}
45   2 // pedantic-note {{first non-designated initializer is here}}
46 };
47 A a3 = {
48   1, // pedantic-note {{first non-designated initializer is here}}
49   .y = 2 // pedantic-error {{mixture of designated and non-designated initializers in the same initializer list is a C99 extension}}
50 };
51 A a4 = {
52   .x = 1, // override-note {{previous}}
53   .x = 1 // override-error {{overrides prior initialization}}
54 }; // wmissing-designated-warning {{missing field 'y' initializer}}
55 A a5 = {
56   .y = 1, // override-note {{previous}}
57   .y = 1 // override-error {{overrides prior initialization}}
58 }; // wmissing-designated-warning {{missing field 'x' initializer}}
59 B b2 = {.a = 1}; // pedantic-error {{brace elision for designated initializer is a C99 extension}}
60                  // wmissing-warning@-1 {{missing field 'y' initializer}}
61 B b3 = {.a = 1, 2}; // pedantic-error {{mixture of designated and non-designated}} pedantic-note {{first non-designated}} pedantic-error {{brace elision}}
62 B b4 = {.a = 1, 2, 3}; // pedantic-error {{mixture of designated and non-designated}} pedantic-note {{first non-designated}} pedantic-error {{brace elision}} expected-error {{excess elements}}
63 B b5 = {.a = nullptr}; // expected-error {{cannot initialize}}
64                        // wmissing-warning@-1 {{missing field 'y' initializer}}
65 struct C { int :0, x, :0, y, :0; };
66 C c = {
67   .x = 1, // override-note {{previous}}
68   .x = 1, // override-error {{overrides prior initialization}} override-note {{previous}}
69   .y = 1, // override-note {{previous}}
70   .y = 1, // override-error {{overrides prior initialization}} // reorder-note {{previous initialization for field 'y' is here}}
71   .x = 1, // reorder-error {{declaration order}} override-error {{overrides prior initialization}} override-note {{previous}}
72   .x = 1, // override-error {{overrides prior initialization}}
73 };
74 
75 struct Foo { int a, b; };
76 
77 struct Foo foo0 = { 1 }; // wmissing-warning {{missing field 'b' initializer}}
78 struct Foo foo1 = { .a = 1 }; // wmissing-designated-warning {{missing field 'b' initializer}}
79 struct Foo foo2 = { .b = 1 }; // wmissing-designated-warning {{missing field 'a' initializer}}
80 
81 }
82 
83 namespace base_class {
84   struct base {
85     int x;
86   };
87   struct derived : base {
88     int y;
89   };
90   derived d = {.x = 1, .y = 2}; // expected-error {{'x' does not refer to any field}}
91 }
92 
93 namespace union_ {
94   union U { int a, b; };
95   U u = {
96     .a = 1, // override-note {{here}}
97     .b = 2, // override-error {{overrides prior}}
98   };
99 }
100 
101 namespace overload_resolution {
102   struct A { int x, y; };
103   union B { int x, y; };
104 
105   void f(A a);
106   void f(B b) = delete;
g()107   void g() { f({.x = 1, .y = 2}); } // ok, calls non-union overload
108 
109   // As an extension of the union case, overload resolution won't pick any
110   // candidate where a field initializer would be overridden.
111   struct A2 { int x, other, y; };
112   int f(A2);
g2()113   void g2() { int k = f({.x = 1, 2, .y = 3}); (void)k; } // pedantic-error {{mixture of designated and non-designated}} pedantic-note {{here}}
114 
115   struct C { int x; };
116   void h(A a); // expected-note {{candidate}}
117   void h(C c); // expected-note {{candidate}}
i()118   void i() {
119     h({.x = 1, .y = 2});
120     h({.y = 1, .x = 2}); // reorder-error {{declaration order}} reorder-note {{previous}}
121     h({.x = 1}); // expected-error {{ambiguous}}
122   }
123 
124   struct D { int y, x; };
125   void j(A a); // expected-note {{candidate}}
126   void j(D d); // expected-note {{candidate}}
k()127   void k() {
128     j({.x = 1, .y = 2}); // expected-error {{ambiguous}}
129   }
130 
131   struct E { A a; };
132   struct F { int a; };
133   void l(E e); // expected-note {{candidate}}
134   int &l(F f); // expected-note {{candidate}}
m()135   void m() {
136     int &r = l({.a = 0}); // ok, l(E) is not viable
137     int &s = l({.a = {0}}); // expected-error {{ambiguous}}
138   }
139 }
140 
141 namespace deduction {
142   struct A { int x, y; };
143   union B { int x, y; };
144 
145   template<typename T, typename U> void f(decltype(T{.x = 1, .y = 2}) = {});
146   template<typename T, typename U> void f(decltype(U{.x = 1, .y = 2}) = {}) = delete;
g()147   void g() { f<A, B>(); } // ok, calls non-union overload
148 
149   struct C { int y, x; };
150   template<typename T, typename U> void h(decltype(T{.y = 1, .x = 2}) = {}) = delete;
151   template<typename T, typename U> void h(decltype(U{.y = 1, .x = 2}) = {});
i()152   void i() {
153     h<A, C>(); // ok, selects C overload by SFINAE
154   }
155 
156   struct D { int n; };
157   struct E { D n; };
158   template<typename T, typename U> void j1(decltype(T{.n = 0}));
159   template<typename T, typename U> void j1(decltype(U{.n = 0})) = delete;
160   template<typename T, typename U> void j2(decltype(T{.n = {0}})); // expected-note {{candidate}}
161   template<typename T, typename U> void j2(decltype(U{.n = {0}})); // expected-note {{candidate}}
162   template<typename T, typename U> void j3(decltype(T{.n = {{0}}})) = delete;
163   template<typename T, typename U> void j3(decltype(U{.n = {{0}}}));
k()164   void k() {
165     j1<D, E>({}); // ok, selects D overload by SFINAE (too few braces for E)
166     j2<D, E>({}); // expected-error {{ambiguous}}
167     j3<D, E>({}); // ok, selects E overload by SFINAE (too many braces for D)
168   }
169 }
170 
171 namespace no_unwrap {
172   template<typename T> struct X {
173     static_assert(false, "should not be instantiated");
174   };
175   struct Q {
176     template<typename T, typename U = typename X<T>::type> Q(T&&);
177   };
178 
179   // Ensure that we do not try to call 'Q::Q(.a = 1)' here.
g()180   void g() { Q q = {.a = 1}; } // expected-error {{initialization of non-aggregate type 'Q' with a designated initializer list}}
181 
182   struct S { int a; };
183   void h(Q q);
184   void h(S s);
185 
186   // OK, does not instantiate X<void&> (!).
i()187   void i() {
188     h({.a = 1});
189   }
190 }
191 
192 namespace GH63605 {
193 struct A  {
194   unsigned x;
195   unsigned y;
196   unsigned z;
197 };
198 
199 struct B {
200   unsigned a;
201   unsigned b;
202 };
203 
204 struct : public A, public B {
205   unsigned : 2;
206   unsigned a : 6;
207   unsigned : 1;
208   unsigned b : 6;
209   unsigned : 2;
210   unsigned c : 6;
211   unsigned d : 1;
212   unsigned e : 2;
213 } data = {
214   {.z=0,
215          // pedantic-note@-1 {{first non-designated initializer is here}}
216          // reorder-note@-2 {{previous initialization for field 'z' is here}}
217    .y=1, // reorder-error {{field 'z' will be initialized after field 'y'}}
218          // reorder-note@-1 {{previous initialization for field 'y' is here}}
219    .x=2}, // reorder-error {{field 'y' will be initialized after field 'x'}}
220   {.b=3,  // reorder-note {{previous initialization for field 'b' is here}}
221    .a=4}, // reorder-error {{field 'b' will be initialized after field 'a'}}
222     .e = 1, // reorder-note {{previous initialization for field 'e' is here}}
223             // pedantic-error@-1 {{mixture of designated and non-designated initializers in the same initializer list is a C99 extension}}
224     .d = 1, // reorder-error {{field 'e' will be initialized after field 'd'}}
225             // reorder-note@-1 {{previous initialization for field 'd' is here}}
226     .c = 1, // reorder-error {{field 'd' will be initialized after field 'c'}} // reorder-note {{previous initialization for field 'c' is here}}
227     .b = 1, // reorder-error {{field 'c' will be initialized after field 'b'}} // reorder-note {{previous initialization for field 'b' is here}}
228     .a = 1, // reorder-error {{field 'b' will be initialized after field 'a'}}
229 };
230 }
231 
232 namespace GH63759 {
233 struct C {
234   int y = 1;
235   union {
236     int a;
237     short b;
238   };
239   int x = 1;
240 };
241 
foo()242 void foo() {
243   C c1 = {.x = 3, .a = 1}; // reorder-error-re {{ISO C++ requires field designators to be specified in declaration order; field 'x' will be initialized after field 'GH63759::C::(anonymous union at {{.*}})'}}
244                            // reorder-note@-1 {{previous initialization for field 'x' is here}}
245 
246   C c2 = {.a = 3, .y = 1}; // reorder-error-re {{ISO C++ requires field designators to be specified in declaration order; field 'GH63759::C::(anonymous union at {{.*}})' will be initialized after field 'y'}}
247                            // reorder-note-re@-1 {{previous initialization for field 'GH63759::C::(anonymous union at {{.*}})' is here}}
248                            //
249 }
250 }
251