Clang Project

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