• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
2 
3 struct one { char c[1]; };
4 struct two { char c[2]; };
5 
6 namespace std {
7   typedef decltype(sizeof(int)) size_t;
8 
9   // libc++'s implementation
10   template <class _E>
11   class initializer_list
12   {
13     const _E* __begin_;
14     size_t    __size_;
15 
initializer_list(const _E * __b,size_t __s)16     initializer_list(const _E* __b, size_t __s)
17       : __begin_(__b),
18         __size_(__s)
19     {}
20 
21   public:
22     typedef _E        value_type;
23     typedef const _E& reference;
24     typedef const _E& const_reference;
25     typedef size_t    size_type;
26 
27     typedef const _E* iterator;
28     typedef const _E* const_iterator;
29 
initializer_list()30     initializer_list() : __begin_(nullptr), __size_(0) {}
31 
size() const32     size_t    size()  const {return __size_;}
begin() const33     const _E* begin() const {return __begin_;}
end() const34     const _E* end()   const {return __begin_ + __size_;}
35   };
36 }
37 
38 namespace objects {
39 
40   struct X1 { X1(int); };
41   struct X2 { explicit X2(int); }; // expected-note {{constructor declared here}}
42 
43   template <int N>
44   struct A {
Aobjects::A45     A() { static_assert(N == 0, ""); }
Aobjects::A46     A(int, double) { static_assert(N == 1, ""); }
47   };
48 
49   template <int N>
50   struct F {
Fobjects::F51     F() { static_assert(N == 0, ""); }
Fobjects::F52     F(int, double) { static_assert(N == 1, ""); }
Fobjects::F53     F(std::initializer_list<int>) { static_assert(N == 3, ""); }
54   };
55 
56   template <int N>
57   struct D {
Dobjects::D58     D(std::initializer_list<int>) { static_assert(N == 0, ""); } // expected-note 1 {{candidate}}
Dobjects::D59     D(std::initializer_list<double>) { static_assert(N == 1, ""); } // expected-note 1 {{candidate}}
60   };
61 
62   template <int N>
63   struct E {
Eobjects::E64     E(int, int) { static_assert(N == 0, ""); }
Eobjects::E65     E(X1, int) { static_assert(N == 1, ""); }
66   };
67 
overload_resolution()68   void overload_resolution() {
69     { A<0> a{}; }
70     { A<0> a = {}; }
71     { A<1> a{1, 1.0}; }
72     { A<1> a = {1, 1.0}; }
73 
74     { F<0> f{}; }
75     { F<0> f = {}; }
76     // Narrowing conversions don't affect viability. The next two choose
77     // the initializer_list constructor.
78     // FIXME: Emit narrowing conversion errors.
79     { F<3> f{1, 1.0}; } // xpected-error {{narrowing conversion}}
80     { F<3> f = {1, 1.0}; } // xpected-error {{narrowing conversion}}
81     { F<3> f{1, 2, 3, 4, 5, 6, 7, 8}; }
82     { F<3> f = {1, 2, 3, 4, 5, 6, 7, 8}; }
83     { F<3> f{1, 2, 3, 4, 5, 6, 7, 8}; }
84     { F<3> f{1, 2}; }
85 
86     { D<0> d{1, 2, 3}; }
87     { D<1> d{1.0, 2.0, 3.0}; }
88     { D<-1> d{1, 2.0}; } // expected-error {{ambiguous}}
89 
90     { E<0> e{1, 2}; }
91   }
92 
explicit_implicit()93   void explicit_implicit() {
94     { X1 x{0}; }
95     { X1 x = {0}; }
96     { X2 x{0}; }
97     { X2 x = {0}; } // expected-error {{constructor is explicit}}
98   }
99 
100   struct C {
101     C();
102     C(int, double);
103     C(int, int);
104 
105     int operator[](C);
106   };
107 
function_call()108   C function_call() {
109     void takes_C(C);
110     takes_C({1, 1.0});
111 
112     C c;
113     c[{1, 1.0}];
114 
115     return {1, 1.0};
116   }
117 
inline_init()118   void inline_init() {
119     (void) C{1, 1.0};
120     (void) new C{1, 1.0};
121     (void) A<1>{1, 1.0};
122     (void) new A<1>{1, 1.0};
123   }
124 
125   struct B { // expected-note 2 {{candidate constructor}}
126     B(C, int, C); // expected-note {{candidate constructor not viable: cannot convert initializer list argument to 'objects::C'}}
127   };
128 
nested_init()129   void nested_init() {
130     B b1{{1, 1.0}, 2, {3, 4}};
131     B b2{{1, 1.0, 4}, 2, {3, 4}}; // expected-error {{no matching constructor for initialization of 'objects::B'}}
132   }
133 
overloaded_call()134   void overloaded_call() {
135     one ov1(B); // expected-note {{not viable: cannot convert initializer list}}
136     two ov1(C); // expected-note {{not viable: cannot convert initializer list}}
137 
138     static_assert(sizeof(ov1({})) == sizeof(two), "bad overload");
139     static_assert(sizeof(ov1({1, 2})) == sizeof(two), "bad overload");
140     static_assert(sizeof(ov1({{1, 1.0}, 2, {3, 4}})) == sizeof(one), "bad overload");
141 
142     ov1({1}); // expected-error {{no matching function}}
143 
144     one ov2(int);
145     two ov2(F<3>);
146     static_assert(sizeof(ov2({1})) == sizeof(one), "bad overload"); // list -> int ranks as identity
147     static_assert(sizeof(ov2({1, 2, 3})) == sizeof(two), "bad overload"); // list -> F only viable
148   }
149 
150   struct G { // expected-note 6 {{not viable}}
151     // This is not an initializer-list constructor.
152     template<typename ...T>
153     G(std::initializer_list<int>, T ...);  // expected-note 3 {{not viable}}
154   };
155 
156   struct H { // expected-note 6 {{not viable}}
157     explicit H(int, int); // expected-note 3 {{not viable}} expected-note {{declared here}}
158     H(int, void*); // expected-note 3 {{not viable}}
159   };
160 
edge_cases()161   void edge_cases() {
162     // invalid (the first phase only considers init-list ctors)
163     // (for the second phase, no constructor is viable)
164     G g1{1, 2, 3}; // expected-error {{no matching constructor}}
165     (void) new G{1, 2, 3}; // expected-error {{no matching constructor}}
166     (void) G{1, 2, 3} // expected-error {{no matching constructor}}
167 
168     // valid (T deduced to <>).
169     G g2({1, 2, 3});
170     (void) new G({1, 2, 3});
171     (void) G({1, 2, 3});
172 
173     // invalid
174     H h1({1, 2}); // expected-error {{no matching constructor}}
175     (void) new H({1, 2}); // expected-error {{no matching constructor}}
176     // FIXME: Bad diagnostic, mentions void type instead of init list.
177     (void) H({1, 2}); // expected-error {{no matching conversion}}
178 
179     // valid (by copy constructor).
180     H h2({1, nullptr});
181     (void) new H({1, nullptr});
182     (void) H({1, nullptr});
183 
184     // valid
185     H h3{1, 2};
186     (void) new H{1, 2};
187     (void) H{1, 2};
188   }
189 
190   struct memberinit {
191     H h1{1, nullptr};
192     H h2 = {1, nullptr};
193     H h3{1, 1};
194     H h4 = {1, 1}; // expected-error {{constructor is explicit}}
195   };
196 }
197 
198 namespace PR12092 {
199 
200   struct S {
201     S(const char*);
202   };
203   struct V {
204     template<typename T> V(T, T);
205     void f(std::initializer_list<S>);
206     void f(const V &);
207   };
208 
g()209   void g() {
210     extern V s;
211     s.f({"foo", "bar"});
212   }
213 
214 }
215 
216 namespace PR12117 {
217   struct A { A(int); };
218   struct B { B(A); } b{{0}};
219   struct C { C(int); } c{0};
220 }
221 
222 namespace PR12167 {
223   template<int N> struct string {};
224 
225   struct X {
226     X(const char v);
227     template<typename T> bool operator()(T) const;
228   };
229 
g(const string<N> & s,Comparator cmp)230   template<int N, class Comparator> bool g(const string<N>& s, Comparator cmp) {
231     return cmp(s);
232   }
f(const string<N> & s)233   template<int N> bool f(const string<N> &s) {
234     return g(s, X{'x'});
235   }
236 
237   bool s = f(string<1>());
238 }
239 
240 namespace PR12257_PR12241 {
241   struct command_pair
242   {
243     command_pair(int, int);
244   };
245 
246   struct command_map
247   {
248     command_map(std::initializer_list<command_pair>);
249   };
250 
251   struct generator_pair
252   {
253     generator_pair(const command_map);
254   };
255 
256   // 5 levels: init list, gen_pair, command_map, init list, command_pair
257   const std::initializer_list<generator_pair> x = {{{{{3, 4}}}}};
258 
259   // 4 levels: init list, gen_pair, command_map via init list, command_pair
260   const std::initializer_list<generator_pair> y = {{{{1, 2}}}};
261 }
262 
263 namespace PR12120 {
264   struct A { explicit A(int); A(float); }; // expected-note {{declared here}}
265   A a = { 0 }; // expected-error {{constructor is explicit}}
266 
267   struct B { explicit B(short); B(long); }; // expected-note 2 {{candidate}}
268   B b = { 0 }; // expected-error {{ambiguous}}
269 }
270 
271 namespace PR12498 {
272   class ArrayRef; // expected-note{{forward declaration}}
273 
274   struct C {
275     void foo(const ArrayRef&); // expected-note{{passing argument to parameter here}}
276   };
277 
bar(C * c)278   static void bar(C* c)
279   {
280     c->foo({ nullptr, 1 }); // expected-error{{initialization of incomplete type 'const PR12498::ArrayRef'}}
281   }
282 
283 }
284