xref: /llvm-project/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp (revision 15f3cd6bfc670ba6106184a903eb04be059e5977)
1 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2 // RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s
3 // RUN: %clang_cc1 -std=c++1z -fsyntax-only -verify %s
4 
5 namespace std {
6   typedef decltype(sizeof(int)) size_t;
7 
8   template <typename E>
9   struct initializer_list
10   {
11     const E *p;
12     size_t n;
initializer_liststd::initializer_list13     initializer_list(const E *p, size_t n) : p(p), n(n) {}
14   };
15 
16   struct string {
17     string(const char *);
18   };
19 
20   template<typename A, typename B>
21   struct pair {
22     pair(const A&, const B&);
23   };
24 }
25 
26 namespace bullet1 {
27   double ad[] = { 1, 2.0 };
28   int ai[] = { 1, 2.0 };  // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}}
29 
30   struct S2 {
31     int m1;
32     double m2, m3;
33   };
34 
35   S2 s21 = { 1, 2, 3.0 };
36   S2 s22 { 1.0, 2, 3 };  // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}}
37   S2 s23 { };
38 }
39 
40 namespace bullet4_example1 {
41   struct S {
Sbullet4_example1::S42     S(std::initializer_list<double> d) {}
Sbullet4_example1::S43     S(std::initializer_list<int> i) {}
Sbullet4_example1::S44     S() {}
45   };
46 
47   S s1 = { 1.0, 2.0, 3.0 };
48   S s2 = { 1, 2, 3 };
49   S s3 = { };
50 }
51 
52 namespace bullet4_example2 {
53   struct Map {
Mapbullet4_example2::Map54     Map(std::initializer_list<std::pair<std::string,int>>) {}
55   };
56 
57   Map ship = {{"Sophie",14}, {"Surprise",28}};
58 }
59 
60 namespace bullet4_example3 {
61   struct S {
Sbullet4_example3::S62     S(int, double, double) {}
Sbullet4_example3::S63     S() {}
64   };
65 
66   S s1 = { 1, 2, 3.0 };
67   S s2 { 1.0, 2, 3 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}}
68   S s3 {};
69 }
70 
71 namespace bullet5 {
72   int x1 {2};
73   int x2 {2.0};  // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}}
74 }
75 
76 namespace bullet6 {
77   struct S {
Sbullet6::S78     S(std::initializer_list<double>) {}
Sbullet6::S79     S(const std::string &) {}
80   };
81 
82   const S& r1 = { 1, 2, 3.0 };
83   const S& r2 = { "Spinach" };
84   S& r3 = { 1, 2, 3 };  // expected-error {{non-const lvalue reference to type 'S' cannot bind to an initializer list temporary}}
85   const int& i1 = { 1 };
86   const int& i2 = { 1.1 };  // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}} expected-warning {{implicit conversion}}
87   const int (&iar)[2] = { 1, 2 };
88 
89   // We interpret "class type with a default constructor" as including the case
90   // where a default constructor is inherited.
91   struct X {
92     X();
93     X(std::initializer_list<int>) = delete;
94   };
95   struct Y : X {
96     using X::X;
97     Y(int);
98   };
99   Y y1{};
use()100   void use() { Y y; }
101   Y y2{};
102 }
103 
104 namespace bullet7 {
105   int** pp {};
106 }
107 
108 namespace bullet8 {
109   struct A { int i; int j; };
110   A a1 { 1, 2 };
111   A a2 { 1.2 };  // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}} expected-warning {{implicit conversion}}
112 
113   struct B {
Bbullet8::B114     B(std::initializer_list<int> i) {}
115   };
116   B b1 { 1, 2 };
117   B b2 { 1, 2.0 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}}
118 
119   struct C {
Cbullet8::C120     C(int i, double j) {}
121   };
122   C c1 = { 1, 2.2 };
123   // FIXME: Suppress the narrowing warning in the cases where we issue a narrowing error.
124   C c2 = { 1.1, 2 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}} expected-warning {{implicit conversion}}
125 
126   int j { 1 };
127   int k { };
128 }
129 
130 namespace rdar13395022 {
131   struct MoveOnly { // expected-note {{candidate}}
132     MoveOnly(MoveOnly&&); // expected-note 2{{copy constructor is implicitly deleted because}} expected-note {{candidate}}
133   };
134 
test(MoveOnly mo)135   void test(MoveOnly mo) {
136     auto &&list1 = {mo}; // expected-error {{call to implicitly-deleted copy constructor}} expected-note {{in initialization of temporary of type 'std::initializer_list}}
137     MoveOnly (&&list2)[1] = {mo}; // expected-error {{call to implicitly-deleted copy constructor}} expected-note {{in initialization of temporary of type 'MoveOnly[1]'}}
138     std::initializer_list<MoveOnly> &&list3 = {};
139     MoveOnly (&&list4)[1] = {}; // expected-error {{no matching constructor}}
140     // expected-note@-1 {{in implicit initialization of array element 0 with omitted initializer}}
141     // expected-note@-2 {{in initialization of temporary of type 'MoveOnly[1]' created to list-initialize this reference}}
142   }
143 }
144 
145 namespace cxx1z_direct_enum_init {
146   enum A {};
147   enum B : char {};
148   enum class C {};
149   enum class D : char {};
150   enum class E : char { k = 5 };
151 
good()152   template<typename T> void good() {
153     (void)T{0};
154     T t1{0};
155     T t2 = T{0};
156 
157     struct S { T t; };
158     S s{T{0}};
159 
160     struct U { T t{0}; } u; // expected-note 0+{{instantiation of}}
161 
162     struct V { T t; V() : t{0} {} }; // expected-note 0+{{instantiation of}}
163 
164     void f(T);
165     f(T{0});
166 
167     char c;
168     auto t3 = T{c};
169   }
170 #if __cplusplus <= 201402L
171   // expected-error@-18 5{{cannot initialize}}
172   // expected-error@-18 5{{cannot initialize}}
173   // expected-error@-18 5{{cannot initialize}}
174   //
175   //
176   // expected-error@-18 5{{cannot initialize}}
177   //
178   // expected-error@-18 5{{cannot initialize}}
179   //
180   // expected-error@-18 5{{cannot initialize}}
181   //
182   //
183   // expected-error@-18 5{{cannot initialize}}
184   //
185   //
186   // expected-error@-18 5{{cannot initialize}}
187 #else
188   // expected-error@-35 {{cannot initialize}}
189   // expected-error@-35 {{cannot initialize}}
190   // expected-error@-35 {{cannot initialize}}
191   //
192   //
193   // expected-error@-35 {{cannot initialize}}
194   //
195   // expected-error@-35 {{cannot initialize}}
196   //
197   // expected-error@-35 {{cannot initialize}}
198   //
199   //
200   // expected-error@-35 {{cannot initialize}}
201   //
202   //
203   // expected-error@-35 {{cannot initialize}}
204 #endif
205 
bad()206   template<typename T> void bad() {
207     T t = {0};
208 
209     struct S { T t; };
210     S s1{0};
211     S s2{{0}};
212 
213     struct U { T t = {0}; } u; // expected-note 0+{{instantiation of}}
214 
215     struct V { T t; V() : t({0}) {} }; // expected-note 0+{{instantiation of}}
216 
217     void f(T); // expected-note 0+{{passing argument}}
218     f({0});
219   }
220   // expected-error@-13 5{{cannot initialize}}
221   //
222   //
223   // expected-error@-13 5{{cannot initialize}}
224   // expected-error@-13 5{{cannot initialize}}
225   //
226   // expected-error@-13 5{{cannot initialize}}
227   //
228   // expected-error@-13 5{{cannot initialize}}
229   //
230   //
231   // expected-error@-13 5{{cannot initialize}}
232 
ugly()233   template<typename T> void ugly() {
234     extern char c;
235     T t1{char('0' + c)};
236     T t2{'0' + c};
237     T t3{1234};
238   }
239 #if __cplusplus <= 201402L
240   // expected-error@-5 4{{cannot initialize}}
241   // expected-error@-5 4{{cannot initialize}}
242   // expected-error@-5 4{{cannot initialize}}
243 #else
244   // expected-error@-8 3{{non-constant-expression cannot be narrowed}}
245   // expected-error@-8 3{{constant expression evaluates to 1234 which cannot be narrowed}} expected-warning@-8 {{changes value}}
246 #endif
247 
test()248   void test() {
249     good<A>(); // expected-note 4{{instantiation of}}
250     good<B>();
251     good<C>();
252     good<D>();
253     good<E>();
254 #if __cplusplus <= 201402L
255     // expected-note@-5 4{{instantiation of}}
256     // expected-note@-5 4{{instantiation of}}
257     // expected-note@-5 4{{instantiation of}}
258     // expected-note@-5 4{{instantiation of}}
259 #endif
260 
261     bad<A>(); // expected-note 4{{instantiation of}}
262     bad<B>(); // expected-note 4{{instantiation of}}
263     bad<C>(); // expected-note 4{{instantiation of}}
264     bad<D>(); // expected-note 4{{instantiation of}}
265     bad<E>(); // expected-note 4{{instantiation of}}
266 
267     ugly<B>(); // expected-note {{instantiation of}}
268     ugly<C>(); // ok
269     ugly<D>(); // expected-note {{instantiation of}}
270     ugly<E>(); // expected-note {{instantiation of}}
271 #if __cplusplus <= 201402L
272     // expected-note@-4 {{instantiation of}}
273 #else
274     (void)B{0.0}; // expected-error {{type 'double' cannot be narrowed}}
275 #endif
276   }
277 
278 #if __cplusplus > 201402L
279   enum class F : unsigned {};
f1(unsigned x)280   F f1(unsigned x) { return F{x}; }
f2(const unsigned x)281   F f2(const unsigned x) { return F{x}; }
f3(bool x)282   F f3(bool x) { return F{x}; }
f4(const bool x)283   F f4(const bool x) { return F{x}; }
284 #endif
285 }
286