Clang Project

clang_source_code/test/SemaCXX/cxx0x-initializer-constructor.cpp
1// RUN: %clang_cc1 -std=c++0x -fsyntax-only -fexceptions -verify %s
2
3struct one { char c[1]; };
4struct two { char c[2]; };
5
6namespace 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
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
30    initializer_list() : __begin_(nullptr), __size_(0) {}
31
32    size_t    size()  const {return __size_;}
33    const _E* begin() const {return __begin_;}
34    const _E* end()   const {return __begin_ + __size_;}
35  };
36}
37
38namespace 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 {
45    A() { static_assert(N == 0, ""); }
46    A(int, double) { static_assert(N == 1, ""); }
47  };
48
49  template <int N>
50  struct F {
51    F() { static_assert(N == 0, ""); }
52    F(int, double) { static_assert(N == 1, ""); }
53    F(std::initializer_list<int>) { static_assert(N == 3, ""); }
54  };
55
56  template <int N>
57  struct D {
58    D(std::initializer_list<int>) { static_assert(N == 0, ""); } // expected-note 1 {{candidate}}
59    D(std::initializer_list<double>) { static_assert(N == 1, ""); } // expected-note 1 {{candidate}}
60  };
61
62  template <int N>
63  struct E {
64    E(int, int) { static_assert(N == 0, ""); }
65    E(X1, int) { static_assert(N == 1, ""); }
66  };
67
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    { F<3> f{1, 1.0}; } // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}}
79    { F<3> f = {1, 1.0}; } // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}}
80    { F<3> f{1, 2, 3, 4, 5, 6, 7, 8}; }
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}; }
84
85    { D<0> d{1, 2, 3}; }
86    { D<1> d{1.0, 2.0, 3.0}; }
87    { D<-1> d{1, 2.0}; } // expected-error {{ambiguous}}
88
89    { E<0> e{1, 2}; }
90  }
91
92  void explicit_implicit() {
93    { X1 x{0}; }
94    { X1 x = {0}; }
95    { X2 x{0}; }
96    { X2 x = {0}; } // expected-error {{constructor is explicit}}
97  }
98
99  struct C {
100    C();
101    C(int, double);
102    C(int, int);
103
104    int operator[](C);
105  };
106
107  C function_call() {
108    void takes_C(C);
109    takes_C({1, 1.0});
110
111    C c;
112    c[{1, 1.0}];
113
114    return {1, 1.0};
115  }
116
117  void inline_init() {
118    (void) C{1, 1.0};
119    (void) new C{1, 1.0};
120    (void) A<1>{1, 1.0};
121    (void) new A<1>{1, 1.0};
122  }
123
124  struct B { // expected-note 2 {{candidate constructor}}
125    B(C, int, C); // expected-note {{candidate constructor not viable: cannot convert initializer list argument to 'objects::C'}}
126  };
127
128  void nested_init() {
129    B b1{{1, 1.0}, 2, {3, 4}};
130    B b2{{1, 1.0, 4}, 2, {3, 4}}; // expected-error {{no matching constructor for initialization of 'objects::B'}}
131  }
132
133  void overloaded_call() {
134    one ov1(B); // expected-note {{not viable: cannot convert initializer list}}
135    two ov1(C); // expected-note {{not viable: cannot convert initializer list}}
136
137    static_assert(sizeof(ov1({})) == sizeof(two), "bad overload");
138    static_assert(sizeof(ov1({1, 2})) == sizeof(two), "bad overload");
139    static_assert(sizeof(ov1({{1, 1.0}, 2, {3, 4}})) == sizeof(one), "bad overload");
140
141    ov1({1}); // expected-error {{no matching function}}
142
143    one ov2(int);
144    two ov2(F<3>);
145    // expected-warning@+1 {{braces around scalar initializer}}
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
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    (void) H({1, 2}); // expected-error {{no matching constructor}}
177
178    // valid (by copy constructor).
179    H h2({1, nullptr});
180    (void) new H({1, nullptr});
181    (void) H({1, nullptr});
182
183    // valid
184    H h3{1, 2};
185    (void) new H{1, 2};
186    (void) H{1, 2};
187  }
188
189  struct memberinit {
190    H h1{1, nullptr};
191    H h2 = {1, nullptr};
192    H h3{1, 1};
193    H h4 = {1, 1}; // expected-error {{constructor is explicit}}
194  };
195}
196
197namespace PR12092 {
198
199  struct S {
200    S(const char*);
201  };
202  struct V {
203    template<typename T> V(T, T);
204    void f(std::initializer_list<S>);
205    void f(const V &);
206  };
207
208  void g() {
209    extern V s;
210    s.f({"foo", "bar"});
211  }
212
213}
214
215namespace PR12117 {
216  struct A { A(int); }; 
217  struct B { B(A); } b{{0}};   //FIXME: non-conformant. Temporary fix until standard resolution.
218                                // expected- error {{call to constructor of 'struct B' is ambiguous}} \
219                                // expected- note 2{{candidate is the implicit}} \
220                                // expected- note {{candidate constructor}}
221  struct C { C(int); } c{0};
222}
223
224namespace PR12167 {
225  template<int N> struct string {};
226
227  struct X {
228    X(const char v);
229    template<typename T> bool operator()(T) const;
230  };
231
232  template<int N, class Comparator> bool g(const string<N>& s, Comparator cmp) {
233    return cmp(s);
234  }
235  template<int N> bool f(const string<N> &s) {
236    return g(s, X{'x'});
237  }
238
239  bool s = f(string<1>());
240}
241
242namespace PR12257_PR12241 {
243  struct command_pair
244  {
245    command_pair(int, int);
246  };
247
248  struct command_map
249  {
250    command_map(std::initializer_list<command_pair>);
251  };
252
253  struct generator_pair
254  {
255    generator_pair(const command_map);
256  };
257
258  // 5 levels: init list, gen_pair, command_map, init list, command_pair
259  const std::initializer_list<generator_pair> x = {{{{{3, 4}}}}};
260
261  // 4 levels: init list, gen_pair, command_map via init list, command_pair
262  const std::initializer_list<generator_pair> y = {{{{1, 2}}}};
263}
264
265namespace PR12120 {
266  struct A { explicit A(int); A(float); }; // expected-note {{declared here}}
267  A a = { 0 }; // expected-error {{constructor is explicit}}
268
269  struct B { explicit B(short); B(long); }; // expected-note 4{{candidate}}
270  B b = { 0 }; // expected-error {{ambiguous}}
271
272  struct C { explicit C(short); C(long); }; // expected-note 2{{candidate}}
273  C c = {{ 0 }}; // expected-error {{ambiguous}}
274}
275
276namespace PR12498 {
277  class ArrayRef; // expected-note{{forward declaration}}
278
279  struct C {
280    void foo(const ArrayRef&); // expected-note{{passing argument to parameter here}}
281  };
282
283  static void bar(C* c)
284  {
285    c->foo({ nullptr, 1 }); // expected-error{{initialization of incomplete type 'const PR12498::ArrayRef'}}
286  }
287}
288
289namespace explicit_default {
290  struct A {
291    explicit A(); // expected-note{{here}}
292  };
293  A a {}; // ok
294  // This is copy-list-initialization, and we choose an explicit constructor
295  // (even though we do so via value-initialization), so the initialization is
296  // ill-formed.
297  A b = {}; // expected-error{{chosen constructor is explicit}}
298}
299
300namespace init_list_default {
301  struct A {
302    A(std::initializer_list<int>);
303  };
304  A a {}; // calls initializer list constructor
305
306  struct B {
307    B();
308    B(std::initializer_list<int>) = delete;
309  };
310  B b {}; // calls default constructor
311}
312
313// PR13470, <rdar://problem/11974632>
314namespace PR13470 {
315  struct W {
316    explicit W(int); // expected-note {{here}}
317  };
318
319  struct X {
320    X(const X&) = delete; // expected-note 3 {{here}}
321    X(int);
322  };
323
324  template<typename T, typename Fn> void call(Fn f) {
325    f({1}); // expected-error {{constructor is explicit}}
326    f(T{1}); // expected-error {{call to deleted constructor}}
327  }
328
329  void ref_w(const W &); // expected-note 2 {{not viable}}
330  void call_ref_w() {
331    ref_w({1}); // expected-error {{no matching function}}
332    ref_w(W{1});
333    call<W>(ref_w); // expected-note {{instantiation of}}
334  }
335
336  void ref_x(const X &);
337  void call_ref_x() {
338    ref_x({1});
339    ref_x(X{1});
340    call<X>(ref_x); // ok
341  }
342
343  void val_x(X); // expected-note 2 {{parameter}}
344  void call_val_x() {
345    val_x({1});
346    val_x(X{1}); // expected-error {{call to deleted constructor}}
347    call<X>(val_x); // expected-note {{instantiation of}}
348  }
349
350  template<typename T>
351  struct Y {
352    X x{1};
353    void f() { X x{1}; }
354    void h() {
355      ref_w({1}); // expected-error {{no matching function}}
356      ref_w(W{1});
357      ref_x({1});
358      ref_x(X{1});
359      val_x({1});
360      val_x(X{1}); // expected-error {{call to deleted constructor}}
361    }
362    Y() {}
363    Y(int) : x{1} {}
364  };
365
366  Y<int> yi;
367  Y<int> yi2(0);
368  void g() {
369    yi.f();
370    yi.h(); // ok, all diagnostics produced in template definition
371  }
372}
373
374namespace PR19729 {
375  struct A {
376    A(int);
377    A(const A&) = delete;
378  };
379  struct B {
380    void *operator new(std::size_t, A);
381  };
382  B *p = new ({123}) B;
383}
384
385namespace PR11410 {
386  struct A {
387    A() = delete; // expected-note 2{{deleted here}}
388    A(int);
389  };
390
391  A a[3] = {
392    {1}, {2}
393  }; // expected-error {{call to deleted constructor}} \
394        expected-note {{in implicit initialization of array element 2 with omitted initializer}}
395
396  struct B {
397    A a; // expected-note {{in implicit initialization of field 'a'}}
398  } b = {
399  }; // expected-error {{call to deleted constructor}}
400
401  struct C {
402    C(int = 0); // expected-note 2{{candidate}}
403    C(float = 0); // expected-note 2{{candidate}}
404  };
405  C c[3] = {
406    0, 1
407  }; // expected-error {{ambiguous}} expected-note {{in implicit initialization of array element 2}}
408  C c2[3] = {
409    [0] = 1, [2] = 3
410  }; // expected-error {{ambiguous}} expected-note {{in implicit initialization of array element 1}}
411}
412