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 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 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 { 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 // 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 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 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 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 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 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 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 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 230 template<int N, class Comparator> bool g(const string<N>& s, Comparator cmp) { 231 return cmp(s); 232 } 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 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