Home | History | Annotate | Download | only in SemaCXX
      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