// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s struct one { char c[1]; }; struct two { char c[2]; }; namespace std { typedef decltype(sizeof(int)) size_t; // libc++'s implementation template class initializer_list { const _E* __begin_; size_t __size_; initializer_list(const _E* __b, size_t __s) : __begin_(__b), __size_(__s) {} public: typedef _E value_type; typedef const _E& reference; typedef const _E& const_reference; typedef size_t size_type; typedef const _E* iterator; typedef const _E* const_iterator; initializer_list() : __begin_(nullptr), __size_(0) {} size_t size() const {return __size_;} const _E* begin() const {return __begin_;} const _E* end() const {return __begin_ + __size_;} }; } namespace objects { struct X1 { X1(int); }; struct X2 { explicit X2(int); }; // expected-note {{constructor declared here}} template struct A { A() { static_assert(N == 0, ""); } A(int, double) { static_assert(N == 1, ""); } }; template struct F { F() { static_assert(N == 0, ""); } F(int, double) { static_assert(N == 1, ""); } F(std::initializer_list) { static_assert(N == 3, ""); } }; template struct D { D(std::initializer_list) { static_assert(N == 0, ""); } // expected-note 1 {{candidate}} D(std::initializer_list) { static_assert(N == 1, ""); } // expected-note 1 {{candidate}} }; template struct E { E(int, int) { static_assert(N == 0, ""); } E(X1, int) { static_assert(N == 1, ""); } }; void overload_resolution() { { A<0> a{}; } { A<0> a = {}; } { A<1> a{1, 1.0}; } { A<1> a = {1, 1.0}; } { F<0> f{}; } { F<0> f = {}; } // Narrowing conversions don't affect viability. The next two choose // the initializer_list constructor. { F<3> f{1, 1.0}; } // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} { F<3> f = {1, 1.0}; } // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} { F<3> f{1, 2, 3, 4, 5, 6, 7, 8}; } { F<3> f = {1, 2, 3, 4, 5, 6, 7, 8}; } { F<3> f{1, 2, 3, 4, 5, 6, 7, 8}; } { F<3> f{1, 2}; } { D<0> d{1, 2, 3}; } { D<1> d{1.0, 2.0, 3.0}; } { D<-1> d{1, 2.0}; } // expected-error {{ambiguous}} { E<0> e{1, 2}; } } void explicit_implicit() { { X1 x{0}; } { X1 x = {0}; } { X2 x{0}; } { X2 x = {0}; } // expected-error {{constructor is explicit}} } struct C { C(); C(int, double); C(int, int); int operator[](C); }; C function_call() { void takes_C(C); takes_C({1, 1.0}); C c; c[{1, 1.0}]; return {1, 1.0}; } void inline_init() { (void) C{1, 1.0}; (void) new C{1, 1.0}; (void) A<1>{1, 1.0}; (void) new A<1>{1, 1.0}; } struct B { // expected-note 2 {{candidate constructor}} B(C, int, C); // expected-note {{candidate constructor not viable: cannot convert initializer list argument to 'objects::C'}} }; void nested_init() { B b1{{1, 1.0}, 2, {3, 4}}; B b2{{1, 1.0, 4}, 2, {3, 4}}; // expected-error {{no matching constructor for initialization of 'objects::B'}} } void overloaded_call() { one ov1(B); // expected-note {{not viable: cannot convert initializer list}} two ov1(C); // expected-note {{not viable: cannot convert initializer list}} static_assert(sizeof(ov1({})) == sizeof(two), "bad overload"); static_assert(sizeof(ov1({1, 2})) == sizeof(two), "bad overload"); static_assert(sizeof(ov1({{1, 1.0}, 2, {3, 4}})) == sizeof(one), "bad overload"); ov1({1}); // expected-error {{no matching function}} one ov2(int); two ov2(F<3>); static_assert(sizeof(ov2({1})) == sizeof(one), "bad overload"); // list -> int ranks as identity static_assert(sizeof(ov2({1, 2, 3})) == sizeof(two), "bad overload"); // list -> F only viable } struct G { // expected-note 6 {{not viable}} // This is not an initializer-list constructor. template G(std::initializer_list, T ...); // expected-note 3 {{not viable}} }; struct H { // expected-note 6 {{not viable}} explicit H(int, int); // expected-note 3 {{not viable}} expected-note {{declared here}} H(int, void*); // expected-note 3 {{not viable}} }; void edge_cases() { // invalid (the first phase only considers init-list ctors) // (for the second phase, no constructor is viable) G g1{1, 2, 3}; // expected-error {{no matching constructor}} (void) new G{1, 2, 3}; // expected-error {{no matching constructor}} (void) G{1, 2, 3} // expected-error {{no matching constructor}} // valid (T deduced to <>). G g2({1, 2, 3}); (void) new G({1, 2, 3}); (void) G({1, 2, 3}); // invalid H h1({1, 2}); // expected-error {{no matching constructor}} (void) new H({1, 2}); // expected-error {{no matching constructor}} // FIXME: Bad diagnostic, mentions void type instead of init list. (void) H({1, 2}); // expected-error {{no matching conversion}} // valid (by copy constructor). H h2({1, nullptr}); (void) new H({1, nullptr}); (void) H({1, nullptr}); // valid H h3{1, 2}; (void) new H{1, 2}; (void) H{1, 2}; } struct memberinit { H h1{1, nullptr}; H h2 = {1, nullptr}; H h3{1, 1}; H h4 = {1, 1}; // expected-error {{constructor is explicit}} }; } namespace PR12092 { struct S { S(const char*); }; struct V { template V(T, T); void f(std::initializer_list); void f(const V &); }; void g() { extern V s; s.f({"foo", "bar"}); } } namespace PR12117 { struct A { A(int); }; struct B { B(A); } b{{0}}; struct C { C(int); } c{0}; } namespace PR12167 { template struct string {}; struct X { X(const char v); template bool operator()(T) const; }; template bool g(const string& s, Comparator cmp) { return cmp(s); } template bool f(const string &s) { return g(s, X{'x'}); } bool s = f(string<1>()); } namespace PR12257_PR12241 { struct command_pair { command_pair(int, int); }; struct command_map { command_map(std::initializer_list); }; struct generator_pair { generator_pair(const command_map); }; // 5 levels: init list, gen_pair, command_map, init list, command_pair const std::initializer_list x = {{{{{3, 4}}}}}; // 4 levels: init list, gen_pair, command_map via init list, command_pair const std::initializer_list y = {{{{1, 2}}}}; } namespace PR12120 { struct A { explicit A(int); A(float); }; // expected-note {{declared here}} A a = { 0 }; // expected-error {{constructor is explicit}} struct B { explicit B(short); B(long); }; // expected-note 2 {{candidate}} B b = { 0 }; // expected-error {{ambiguous}} } namespace PR12498 { class ArrayRef; // expected-note{{forward declaration}} struct C { void foo(const ArrayRef&); // expected-note{{passing argument to parameter here}} }; static void bar(C* c) { c->foo({ nullptr, 1 }); // expected-error{{initialization of incomplete type 'const PR12498::ArrayRef'}} } } namespace explicit_default { struct A { explicit A(); // expected-note{{here}} }; A a {}; // ok // This is copy-list-initialization, and we choose an explicit constructor // (even though we do so via value-initialization), so the initialization is // ill-formed. A b = {}; // expected-error{{chosen constructor is explicit}} } namespace init_list_default { struct A { A(std::initializer_list); }; A a {}; // calls initializer list constructor struct B { B(); B(std::initializer_list) = delete; }; B b {}; // calls default constructor } // PR13470, namespace PR13470 { struct W { explicit W(int); // expected-note {{here}} }; struct X { X(const X&) = delete; // expected-note 3 {{here}} X(int); }; template void call(Fn f) { f({1}); // expected-error {{constructor is explicit}} f(T{1}); // expected-error {{call to deleted constructor}} } void ref_w(const W &); // expected-note 2 {{not viable}} void call_ref_w() { ref_w({1}); // expected-error {{no matching function}} ref_w(W{1}); call(ref_w); // expected-note {{instantiation of}} } void ref_x(const X &); void call_ref_x() { ref_x({1}); ref_x(X{1}); call(ref_x); // ok } void val_x(X); // expected-note 2 {{parameter}} void call_val_x() { val_x({1}); val_x(X{1}); // expected-error {{call to deleted constructor}} call(val_x); // expected-note {{instantiation of}} } template struct Y { X x{1}; void f() { X x{1}; } void h() { ref_w({1}); // expected-error {{no matching function}} ref_w(W{1}); ref_x({1}); ref_x(X{1}); val_x({1}); val_x(X{1}); // expected-error {{call to deleted constructor}} } Y() {} Y(int) : x{1} {} }; Y yi; Y yi2(0); void g() { yi.f(); yi.h(); // ok, all diagnostics produced in template definition } }