1f4a2713aSLionel Sambuc // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2f4a2713aSLionel Sambuc
3f4a2713aSLionel Sambuc // This must obviously come before the definition of std::initializer_list.
missing_initializerlist()4f4a2713aSLionel Sambuc void missing_initializerlist() {
5f4a2713aSLionel Sambuc auto l = {1, 2, 3, 4}; // expected-error {{std::initializer_list was not found}}
6f4a2713aSLionel Sambuc }
7f4a2713aSLionel Sambuc
8f4a2713aSLionel Sambuc namespace std {
9f4a2713aSLionel Sambuc typedef decltype(sizeof(int)) size_t;
10f4a2713aSLionel Sambuc
11f4a2713aSLionel Sambuc // libc++'s implementation
12f4a2713aSLionel Sambuc template <class _E>
13f4a2713aSLionel Sambuc class initializer_list
14f4a2713aSLionel Sambuc {
15f4a2713aSLionel Sambuc const _E* __begin_;
16f4a2713aSLionel Sambuc size_t __size_;
17f4a2713aSLionel Sambuc
initializer_list(const _E * __b,size_t __s)18f4a2713aSLionel Sambuc initializer_list(const _E* __b, size_t __s)
19f4a2713aSLionel Sambuc : __begin_(__b),
20f4a2713aSLionel Sambuc __size_(__s)
21f4a2713aSLionel Sambuc {}
22f4a2713aSLionel Sambuc
23f4a2713aSLionel Sambuc public:
24f4a2713aSLionel Sambuc typedef _E value_type;
25f4a2713aSLionel Sambuc typedef const _E& reference;
26f4a2713aSLionel Sambuc typedef const _E& const_reference;
27f4a2713aSLionel Sambuc typedef size_t size_type;
28f4a2713aSLionel Sambuc
29f4a2713aSLionel Sambuc typedef const _E* iterator;
30f4a2713aSLionel Sambuc typedef const _E* const_iterator;
31f4a2713aSLionel Sambuc
initializer_list()32f4a2713aSLionel Sambuc initializer_list() : __begin_(nullptr), __size_(0) {}
33f4a2713aSLionel Sambuc
size() const34f4a2713aSLionel Sambuc size_t size() const {return __size_;}
begin() const35f4a2713aSLionel Sambuc const _E* begin() const {return __begin_;}
end() const36f4a2713aSLionel Sambuc const _E* end() const {return __begin_ + __size_;}
37f4a2713aSLionel Sambuc };
38f4a2713aSLionel Sambuc }
39f4a2713aSLionel Sambuc
40f4a2713aSLionel Sambuc template <typename T, typename U>
41f4a2713aSLionel Sambuc struct same_type { static const bool value = false; };
42f4a2713aSLionel Sambuc template <typename T>
43f4a2713aSLionel Sambuc struct same_type<T, T> { static const bool value = true; };
44f4a2713aSLionel Sambuc
45f4a2713aSLionel Sambuc struct one { char c[1]; };
46f4a2713aSLionel Sambuc struct two { char c[2]; };
47f4a2713aSLionel Sambuc
48f4a2713aSLionel Sambuc struct A {
49f4a2713aSLionel Sambuc int a, b;
50f4a2713aSLionel Sambuc };
51f4a2713aSLionel Sambuc
52f4a2713aSLionel Sambuc struct B {
53f4a2713aSLionel Sambuc B();
54f4a2713aSLionel Sambuc B(int, int);
55f4a2713aSLionel Sambuc };
56f4a2713aSLionel Sambuc
simple_list()57f4a2713aSLionel Sambuc void simple_list() {
58f4a2713aSLionel Sambuc std::initializer_list<int> il = { 1, 2, 3 };
59f4a2713aSLionel Sambuc std::initializer_list<double> dl = { 1.0, 2.0, 3 };
60f4a2713aSLionel Sambuc std::initializer_list<A> al = { {1, 2}, {2, 3}, {3, 4} };
61f4a2713aSLionel Sambuc std::initializer_list<B> bl = { {1, 2}, {2, 3}, {} };
62f4a2713aSLionel Sambuc }
63f4a2713aSLionel Sambuc
function_call()64f4a2713aSLionel Sambuc void function_call() {
65f4a2713aSLionel Sambuc void f(std::initializer_list<int>);
66f4a2713aSLionel Sambuc f({1, 2, 3});
67f4a2713aSLionel Sambuc
68f4a2713aSLionel Sambuc void g(std::initializer_list<B>);
69f4a2713aSLionel Sambuc g({ {1, 2}, {2, 3}, {} });
70f4a2713aSLionel Sambuc }
71f4a2713aSLionel Sambuc
72f4a2713aSLionel Sambuc struct C {
73f4a2713aSLionel Sambuc C(int);
74f4a2713aSLionel Sambuc };
75f4a2713aSLionel Sambuc
76f4a2713aSLionel Sambuc struct D {
77f4a2713aSLionel Sambuc D();
78f4a2713aSLionel Sambuc operator int();
79f4a2713aSLionel Sambuc operator C();
80f4a2713aSLionel Sambuc };
81f4a2713aSLionel Sambuc
overloaded_call()82f4a2713aSLionel Sambuc void overloaded_call() {
83f4a2713aSLionel Sambuc one overloaded(std::initializer_list<int>);
84f4a2713aSLionel Sambuc two overloaded(std::initializer_list<B>);
85f4a2713aSLionel Sambuc
86f4a2713aSLionel Sambuc static_assert(sizeof(overloaded({1, 2, 3})) == sizeof(one), "bad overload");
87f4a2713aSLionel Sambuc static_assert(sizeof(overloaded({ {1, 2}, {2, 3}, {} })) == sizeof(two), "bad overload");
88f4a2713aSLionel Sambuc
89f4a2713aSLionel Sambuc void ambiguous(std::initializer_list<A>); // expected-note {{candidate}}
90f4a2713aSLionel Sambuc void ambiguous(std::initializer_list<B>); // expected-note {{candidate}}
91f4a2713aSLionel Sambuc ambiguous({ {1, 2}, {2, 3}, {3, 4} }); // expected-error {{ambiguous}}
92f4a2713aSLionel Sambuc
93f4a2713aSLionel Sambuc one ov2(std::initializer_list<int>); // expected-note {{candidate}}
94f4a2713aSLionel Sambuc two ov2(std::initializer_list<C>); // expected-note {{candidate}}
95f4a2713aSLionel Sambuc // Worst sequence to int is identity, whereas to C it's user-defined.
96f4a2713aSLionel Sambuc static_assert(sizeof(ov2({1, 2, 3})) == sizeof(one), "bad overload");
97f4a2713aSLionel Sambuc // But here, user-defined is worst in both cases.
98f4a2713aSLionel Sambuc ov2({1, 2, D()}); // expected-error {{ambiguous}}
99f4a2713aSLionel Sambuc }
100f4a2713aSLionel Sambuc
101f4a2713aSLionel Sambuc template <typename T>
102f4a2713aSLionel Sambuc T deduce(std::initializer_list<T>); // expected-note {{conflicting types for parameter 'T' ('int' vs. 'double')}}
103f4a2713aSLionel Sambuc template <typename T>
104f4a2713aSLionel Sambuc T deduce_ref(const std::initializer_list<T>&); // expected-note {{conflicting types for parameter 'T' ('int' vs. 'double')}}
105f4a2713aSLionel Sambuc
argument_deduction()106f4a2713aSLionel Sambuc void argument_deduction() {
107f4a2713aSLionel Sambuc static_assert(same_type<decltype(deduce({1, 2, 3})), int>::value, "bad deduction");
108f4a2713aSLionel Sambuc static_assert(same_type<decltype(deduce({1.0, 2.0, 3.0})), double>::value, "bad deduction");
109f4a2713aSLionel Sambuc
110f4a2713aSLionel Sambuc deduce({1, 2.0}); // expected-error {{no matching function}}
111f4a2713aSLionel Sambuc
112f4a2713aSLionel Sambuc static_assert(same_type<decltype(deduce_ref({1, 2, 3})), int>::value, "bad deduction");
113f4a2713aSLionel Sambuc static_assert(same_type<decltype(deduce_ref({1.0, 2.0, 3.0})), double>::value, "bad deduction");
114f4a2713aSLionel Sambuc
115f4a2713aSLionel Sambuc deduce_ref({1, 2.0}); // expected-error {{no matching function}}
116f4a2713aSLionel Sambuc }
117f4a2713aSLionel Sambuc
auto_deduction()118f4a2713aSLionel Sambuc void auto_deduction() {
119f4a2713aSLionel Sambuc auto l = {1, 2, 3, 4};
120*0a6a1f1dSLionel Sambuc auto l2 {1, 2, 3, 4}; // expected-warning {{will change meaning in a future version of Clang}}
121f4a2713aSLionel Sambuc static_assert(same_type<decltype(l), std::initializer_list<int>>::value, "");
122f4a2713aSLionel Sambuc auto bl = {1, 2.0}; // expected-error {{cannot deduce}}
123f4a2713aSLionel Sambuc
124f4a2713aSLionel Sambuc for (int i : {1, 2, 3, 4}) {}
125f4a2713aSLionel Sambuc }
126f4a2713aSLionel Sambuc
dangle()127f4a2713aSLionel Sambuc void dangle() {
128f4a2713aSLionel Sambuc new auto{1, 2, 3}; // expected-error {{cannot use list-initialization}}
129f4a2713aSLionel Sambuc new std::initializer_list<int>{1, 2, 3}; // expected-warning {{at the end of the full-expression}}
130f4a2713aSLionel Sambuc }
131f4a2713aSLionel Sambuc
132f4a2713aSLionel Sambuc struct haslist1 {
133f4a2713aSLionel Sambuc std::initializer_list<int> il = {1, 2, 3}; // expected-warning{{at the end of the constructor}}
134f4a2713aSLionel Sambuc std::initializer_list<int> jl{1, 2, 3}; // expected-warning{{at the end of the constructor}}
135f4a2713aSLionel Sambuc haslist1();
136f4a2713aSLionel Sambuc };
137f4a2713aSLionel Sambuc
haslist1()138f4a2713aSLionel Sambuc haslist1::haslist1()
139f4a2713aSLionel Sambuc : il{1, 2, 3} // expected-warning{{at the end of the constructor}}
140f4a2713aSLionel Sambuc {}
141f4a2713aSLionel Sambuc
142f4a2713aSLionel Sambuc namespace PR12119 {
143f4a2713aSLionel Sambuc // Deduction with nested initializer lists.
144f4a2713aSLionel Sambuc template<typename T> void f(std::initializer_list<T>);
145f4a2713aSLionel Sambuc template<typename T> void g(std::initializer_list<std::initializer_list<T>>);
146f4a2713aSLionel Sambuc
foo()147f4a2713aSLionel Sambuc void foo() {
148f4a2713aSLionel Sambuc f({0, {1}}); // expected-warning{{braces around scalar initializer}}
149f4a2713aSLionel Sambuc g({{0, 1}, {2, 3}});
150f4a2713aSLionel Sambuc std::initializer_list<int> il = {1, 2};
151f4a2713aSLionel Sambuc g({il, {2, 3}});
152f4a2713aSLionel Sambuc }
153f4a2713aSLionel Sambuc }
154f4a2713aSLionel Sambuc
155f4a2713aSLionel Sambuc namespace Decay {
156f4a2713aSLionel Sambuc template<typename T>
f(std::initializer_list<T>)157f4a2713aSLionel Sambuc void f(std::initializer_list<T>) {
158f4a2713aSLionel Sambuc T x = 1; // expected-error{{cannot initialize a variable of type 'const char *' with an rvalue of type 'int'}}
159f4a2713aSLionel Sambuc }
160f4a2713aSLionel Sambuc
g()161f4a2713aSLionel Sambuc void g() {
162f4a2713aSLionel Sambuc f({"A", "BB", "CCC"}); // expected-note{{in instantiation of function template specialization 'Decay::f<const char *>' requested here}}
163f4a2713aSLionel Sambuc
164f4a2713aSLionel Sambuc auto x = { "A", "BB", "CCC" };
165f4a2713aSLionel Sambuc std::initializer_list<const char *> *il = &x;
166f4a2713aSLionel Sambuc
167f4a2713aSLionel Sambuc for( auto s : {"A", "BB", "CCC", "DDD"}) { }
168f4a2713aSLionel Sambuc }
169f4a2713aSLionel Sambuc }
170f4a2713aSLionel Sambuc
171f4a2713aSLionel Sambuc namespace PR12436 {
172f4a2713aSLionel Sambuc struct X {
173f4a2713aSLionel Sambuc template<typename T>
174f4a2713aSLionel Sambuc X(std::initializer_list<int>, T);
175f4a2713aSLionel Sambuc };
176f4a2713aSLionel Sambuc
177f4a2713aSLionel Sambuc X x({}, 17);
178f4a2713aSLionel Sambuc }
179f4a2713aSLionel Sambuc
180f4a2713aSLionel Sambuc namespace rdar11948732 {
181f4a2713aSLionel Sambuc template<typename T> struct X {};
182f4a2713aSLionel Sambuc
183f4a2713aSLionel Sambuc struct XCtorInit {
184f4a2713aSLionel Sambuc XCtorInit(std::initializer_list<X<int>>);
185f4a2713aSLionel Sambuc };
186f4a2713aSLionel Sambuc
f(X<int> & xi)187f4a2713aSLionel Sambuc void f(X<int> &xi) {
188f4a2713aSLionel Sambuc XCtorInit xc = { xi, xi };
189f4a2713aSLionel Sambuc }
190f4a2713aSLionel Sambuc }
191f4a2713aSLionel Sambuc
192f4a2713aSLionel Sambuc namespace PR14272 {
193f4a2713aSLionel Sambuc auto x { { 0, 0 } }; // expected-error {{cannot deduce actual type for variable 'x' with type 'auto' from initializer list}}
194f4a2713aSLionel Sambuc }
195f4a2713aSLionel Sambuc
196f4a2713aSLionel Sambuc namespace initlist_of_array {
f(std::initializer_list<int[2]>)197f4a2713aSLionel Sambuc void f(std::initializer_list<int[2]>) {}
198f4a2713aSLionel Sambuc void f(std::initializer_list<int[2][2]>) = delete;
h()199f4a2713aSLionel Sambuc void h() {
200f4a2713aSLionel Sambuc f({{1,2},{3,4}});
201f4a2713aSLionel Sambuc }
202f4a2713aSLionel Sambuc }
203f4a2713aSLionel Sambuc
204f4a2713aSLionel Sambuc namespace init_list_deduction_failure {
205f4a2713aSLionel Sambuc void f();
206f4a2713aSLionel Sambuc void f(int);
207f4a2713aSLionel Sambuc template<typename T> void g(std::initializer_list<T>);
208f4a2713aSLionel Sambuc // expected-note@-1 {{candidate template ignored: couldn't resolve reference to overloaded function 'f'}}
h()209f4a2713aSLionel Sambuc void h() { g({f}); }
210f4a2713aSLionel Sambuc // expected-error@-1 {{no matching function for call to 'g'}}
211f4a2713aSLionel Sambuc }
212f4a2713aSLionel Sambuc
213f4a2713aSLionel Sambuc namespace deleted_copy {
214f4a2713aSLionel Sambuc struct X {
Xdeleted_copy::X215f4a2713aSLionel Sambuc X(int i) {}
216f4a2713aSLionel Sambuc X(const X& x) = delete; // expected-note {{here}}
217f4a2713aSLionel Sambuc void operator=(const X& x) = delete;
218f4a2713aSLionel Sambuc };
219f4a2713aSLionel Sambuc
220f4a2713aSLionel Sambuc std::initializer_list<X> x{1}; // expected-error {{invokes deleted constructor}}
221f4a2713aSLionel Sambuc }
222f4a2713aSLionel Sambuc
223f4a2713aSLionel Sambuc namespace RefVersusInitList {
224f4a2713aSLionel Sambuc struct S {};
225f4a2713aSLionel Sambuc void f(const S &) = delete;
226f4a2713aSLionel Sambuc void f(std::initializer_list<S>);
g(S s)227f4a2713aSLionel Sambuc void g(S s) { f({S()}); }
228f4a2713aSLionel Sambuc }
229f4a2713aSLionel Sambuc
230f4a2713aSLionel Sambuc namespace PR18013 {
231f4a2713aSLionel Sambuc int f();
232f4a2713aSLionel Sambuc std::initializer_list<long (*)()> x = {f}; // expected-error {{cannot initialize an array element of type 'long (*const)()' with an lvalue of type 'int ()': different return type ('long' vs 'int')}}
233f4a2713aSLionel Sambuc }
234*0a6a1f1dSLionel Sambuc
235*0a6a1f1dSLionel Sambuc namespace DR1070 {
236*0a6a1f1dSLionel Sambuc struct S {
237*0a6a1f1dSLionel Sambuc S(std::initializer_list<int>);
238*0a6a1f1dSLionel Sambuc };
239*0a6a1f1dSLionel Sambuc S s[3] = { {1, 2, 3}, {4, 5} }; // ok
240*0a6a1f1dSLionel Sambuc S *p = new S[3] { {1, 2, 3}, {4, 5} }; // ok
241*0a6a1f1dSLionel Sambuc }
242*0a6a1f1dSLionel Sambuc
243*0a6a1f1dSLionel Sambuc namespace ListInitInstantiate {
244*0a6a1f1dSLionel Sambuc struct A {
245*0a6a1f1dSLionel Sambuc A(std::initializer_list<A>);
246*0a6a1f1dSLionel Sambuc A(std::initializer_list<int>);
247*0a6a1f1dSLionel Sambuc };
248*0a6a1f1dSLionel Sambuc struct B : A {
249*0a6a1f1dSLionel Sambuc B(int);
250*0a6a1f1dSLionel Sambuc };
251*0a6a1f1dSLionel Sambuc template<typename T> struct X {
252*0a6a1f1dSLionel Sambuc X();
253*0a6a1f1dSLionel Sambuc A a;
254*0a6a1f1dSLionel Sambuc };
X()255*0a6a1f1dSLionel Sambuc template<typename T> X<T>::X() : a{B{0}, B{1}} {}
256*0a6a1f1dSLionel Sambuc
257*0a6a1f1dSLionel Sambuc X<int> x;
258*0a6a1f1dSLionel Sambuc
259*0a6a1f1dSLionel Sambuc int f(const A&);
g()260*0a6a1f1dSLionel Sambuc template<typename T> void g() { int k = f({0}); }
261*0a6a1f1dSLionel Sambuc template void g<int>();
262*0a6a1f1dSLionel Sambuc }
263