1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s
3 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 %s
4 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++2a %s
5 
6 // Verify that using an initializer list for a non-aggregate looks for
7 // constructors..
8 struct NonAggr1 { // expected-note 2 {{candidate constructor}}
NonAggr1NonAggr19   NonAggr1(int, int) { } // expected-note {{candidate constructor}}
10 
11   int m;
12 };
13 
14 struct Base { };
15 struct NonAggr2 : public Base { // expected-note 0-3 {{candidate constructor}}
16   int m;
17 };
18 
19 class NonAggr3 { // expected-note 3 {{candidate constructor}}
20   int m;
21 };
22 
23 struct NonAggr4 { // expected-note 3 {{candidate constructor}}
24   int m;
25   virtual void f();
26 };
27 
28 NonAggr1 na1 = { 17 }; // expected-error{{no matching constructor for initialization of 'NonAggr1'}}
29 NonAggr2 na2 = { 17 };
30 NonAggr3 na3 = { 17 }; // expected-error{{no matching constructor for initialization of 'NonAggr3'}}
31 NonAggr4 na4 = { 17 }; // expected-error{{no matching constructor for initialization of 'NonAggr4'}}
32 #if __cplusplus <= 201402L
33 // expected-error@-4{{no matching constructor for initialization of 'NonAggr2'}}
34 #else
35 // expected-error@-6{{requires explicit braces}}
36 NonAggr2 na2b = { {}, 17 }; // ok
37 #endif
38 
39 // PR5817
40 typedef int type[][2];
41 const type foo = {0};
42 
43 // Vector initialization.
44 typedef short __v4hi __attribute__ ((__vector_size__ (8)));
45 __v4hi v1 = { (void *)1, 2, 3 }; // expected-error {{cannot initialize a vector element of type 'short' with an rvalue of type 'void *'}}
46 
47 // Array initialization.
48 int a[] = { (void *)1 }; // expected-error {{cannot initialize an array element of type 'int' with an rvalue of type 'void *'}}
49 
50 // Struct initialization.
51 struct S { int a; } s = { (void *)1 }; // expected-error {{cannot initialize a member subobject of type 'int' with an rvalue of type 'void *'}}
52 
53 // Check that we're copy-initializing the structs.
54 struct A {
55   A();
56   A(int);
57   ~A();
58 
59   A(const A&) = delete; // expected-note 0-2{{'A' has been explicitly marked deleted here}}
60 };
61 
62 struct B {
63   A a;
64 };
65 
66 struct C {
67   const A& a;
68 };
69 
f()70 void f() {
71   A as1[1] = { };
72   A as2[1] = { 1 };
73 #if __cplusplus <= 201402L
74   // expected-error@-2 {{copying array element of type 'A' invokes deleted constructor}}
75 #endif
76 
77   B b1 = { };
78   B b2 = { 1 };
79 #if __cplusplus <= 201402L
80   // expected-error@-2 {{copying member subobject of type 'A' invokes deleted constructor}}
81 #endif
82 
83   C c1 = { 1 };
84 }
85 
86 class Agg {
87 public:
88   int i, j;
89 };
90 
91 class AggAgg {
92 public:
93   Agg agg1;
94   Agg agg2;
95 };
96 
97 AggAgg aggagg = { 1, 2, 3, 4 };
98 
99 namespace diff_cpp14_dcl_init_aggr_example {
100   struct derived;
101   struct base {
102     friend struct derived;
103   private:
104     base();
105   };
106   struct derived : base {};
107 
108   derived d1{};
109 #if __cplusplus > 201402L
110   // expected-error@-2 {{private}}
111   // expected-note@-7 {{here}}
112 #endif
113   derived d2;
114 }
115 
116 namespace ProtectedBaseCtor {
117   // FIXME: It's unclear whether f() and g() should be valid in C++1z. What is
118   // the object expression in a constructor call -- the base class subobject or
119   // the complete object?
120   struct A {
121   protected:
122     A();
123   };
124 
125   struct B : public A {
126     friend B f();
127     friend B g();
128     friend B h();
129   };
130 
f()131   B f() { return {}; }
132 #if __cplusplus > 201402L
133   // expected-error@-2 {{protected default constructor}}
134   // expected-note@-12 {{here}}
135 #endif
136 
g()137   B g() { return {{}}; }
138 #if __cplusplus <= 201402L
139   // expected-error@-2 {{no matching constructor}}
140   // expected-note@-15 3{{candidate}}
141 #else
142   // expected-error@-5 {{protected default constructor}}
143   // expected-note@-21 {{here}}
144 #endif
145 
h()146   B h() { return {A{}}; }
147 #if __cplusplus <= 201402L
148   // expected-error@-2 {{no matching constructor}}
149   // expected-note@-24 3{{candidate}}
150 #endif
151   // expected-error@-5 {{protected constructor}}
152   // expected-note@-30 {{here}}
153 }
154 
155 namespace IdiomaticStdArrayInitDoesNotWarn {
156 #pragma clang diagnostic push
157 #pragma clang diagnostic warning "-Wmissing-braces"
158   template<typename T, int N> struct StdArray {
159     T contents[N];
160   };
161   StdArray<int, 3> x = {1, 2, 3};
162 
163   template<typename T, int N> struct ArrayAndSomethingElse {
164     T contents[N];
165     int something_else;
166   };
167   ArrayAndSomethingElse<int, 3> y = {1, 2, 3}; // expected-warning {{suggest braces}}
168 
169 #if __cplusplus >= 201703L
170   template<typename T, int N> struct ArrayAndBaseClass : StdArray<int, 3> {
171     T contents[N];
172   };
173   ArrayAndBaseClass<int, 3> z = {1, 2, 3}; // expected-warning {{suggest braces}}
174 
175   // This pattern is used for tagged aggregates and must not warn
176   template<typename T, int N> struct JustABaseClass : StdArray<T, N> {};
177   JustABaseClass<int, 3> w = {1, 2, 3};
178   // but this should be also ok
179   JustABaseClass<int, 3> v = {{1, 2, 3}};
180 
181   template <typename T, int N> struct OnionBaseClass : JustABaseClass<T, N> {};
182   OnionBaseClass<int, 3> u = {1, 2, 3};
183   OnionBaseClass<int, 3> t = {{{1, 2, 3}}};
184 
185   struct EmptyBase {};
186 
187   template <typename T, int N> struct AggregateAndEmpty : StdArray<T, N>, EmptyBase {};
188   AggregateAndEmpty<int, 3> p = {1, 2, 3}; // expected-warning {{suggest braces}}
189 #endif
190 
191 #pragma clang diagnostic pop
192 }
193 
194 namespace HugeArraysUseArrayFiller {
195   // All we're checking here is that initialization completes in a reasonable
196   // amount of time.
197   struct A { int n; int arr[1000 * 1000 * 1000]; } a = {1, {2}};
198 }
199 
200 namespace ElementDestructor {
201   // The destructor for each element of class type is potentially invoked
202   // (15.4 [class.dtor]) from the context where the aggregate initialization
203   // occurs. Produce a diagnostic if an element's destructor isn't accessible.
204 
205   class X { int f; ~X(); }; // expected-note {{implicitly declared private here}}
206   struct Y { X x; };
207 
test0()208   void test0() {
209     auto *y = new Y {}; // expected-error {{temporary of type 'ElementDestructor::X' has private destructor}}
210   }
211 
212   struct S0 { int f; ~S0() = delete; }; // expected-note 3 {{'~S0' has been explicitly marked deleted here}}
213   struct S1 { S0 s0; int f; };
214 
test1()215   S1 test1() {
216     auto *t = new S1 { .f = 1 }; // expected-error {{attempt to use a deleted function}}
217     return {2}; // expected-error {{attempt to use a deleted function}}
218   }
219 
220   // Check if the type of an array element has a destructor.
221   struct S2 { S0 a[4]; };
222 
test2()223   void test2() {
224     auto *t = new S2 {1,2,3,4}; // expected-error {{attempt to use a deleted function}}
225   }
226 
227 #if __cplusplus >= 201703L
228   namespace BaseDestructor {
229      struct S0 { int f; ~S0() = delete; }; // expected-note {{'~S0' has been explicitly marked deleted here}}
230 
231     // Check destructor of base class.
232     struct S3 : S0 {};
233 
test3()234     void test3() {
235       S3 s3 = {1}; // expected-error {{attempt to use a deleted function}}
236     }
237   }
238 #endif
239 
240   // A's destructor doesn't have to be accessible from the context of C's
241   // initialization.
242   struct A { friend struct B; private: ~A(); };
243   struct B { B(); A a; };
244   struct C { B b; };
245   C c = { B() };
246 }
247