Home | History | Annotate | Download | only in drs
      1 // RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
      2 // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
      3 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
      4 // RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
      5 
      6 #if __cplusplus < 201103L
      7 // expected-no-diagnostics
      8 #endif
      9 
     10 namespace dr1550 { // dr1550: yes
     11   int f(bool b, int n) {
     12     return (b ? (throw 0) : n) + (b ? n : (throw 0));
     13   }
     14 }
     15 
     16 namespace dr1560 { // dr1560: 3.5
     17   void f(bool b, int n) {
     18     (b ? throw 0 : n) = (b ? n : throw 0) = 0;
     19   }
     20   class X { X(const X&); };
     21   const X &get();
     22   const X &x = true ? get() : throw 0;
     23 }
     24 
     25 namespace dr1573 { // dr1573: 3.9
     26 #if __cplusplus >= 201103L
     27   // ellipsis is inherited (p0136r1 supersedes this part).
     28   struct A { A(); A(int, char, ...); };
     29   struct B : A { using A::A; };
     30   B b(1, 'x', 4.0, "hello"); // ok
     31 
     32   // inherited constructor is effectively constexpr if the user-written constructor would be
     33   struct C { C(); constexpr C(int) {} };
     34   struct D : C { using C::C; };
     35   constexpr D d = D(0); // ok
     36   struct E : C { using C::C; A a; }; // expected-note {{non-literal type}}
     37   constexpr E e = E(0); // expected-error {{non-literal type}}
     38   // FIXME: This diagnostic is pretty bad; we should explain that the problem
     39   // is that F::c would be initialized by a non-constexpr constructor.
     40   struct F : C { using C::C; C c; }; // expected-note {{here}}
     41   constexpr F f = F(0); // expected-error {{constant expression}} expected-note {{constructor inherited from base class 'C'}}
     42 
     43   // inherited constructor is effectively deleted if the user-written constructor would be
     44   struct G { G(int); };
     45   struct H : G { using G::G; G g; }; // expected-note {{constructor inherited by 'H' is implicitly deleted because field 'g' has no default constructor}}
     46   H h(0); // expected-error {{constructor inherited by 'H' from base class 'G' is implicitly deleted}}
     47 #endif
     48 }
     49 
     50 #if __cplusplus >= 201103L
     51 namespace std {
     52   typedef decltype(sizeof(int)) size_t;
     53 
     54   // libc++'s implementation
     55   template <class _E>
     56   class initializer_list
     57   {
     58     const _E* __begin_;
     59     size_t    __size_;
     60 
     61     initializer_list(const _E* __b, size_t __s)
     62     : __begin_(__b), __size_(__s) {}
     63 
     64   public:
     65     typedef _E        value_type;
     66     typedef const _E& reference;
     67     typedef const _E& const_reference;
     68     typedef size_t    size_type;
     69 
     70     typedef const _E* iterator;
     71     typedef const _E* const_iterator;
     72 
     73     initializer_list() : __begin_(nullptr), __size_(0) {}
     74 
     75     size_t    size()  const {return __size_;}
     76     const _E* begin() const {return __begin_;}
     77     const _E* end()   const {return __begin_ + __size_;}
     78   };
     79 
     80   template < class _T1, class _T2 > struct pair { _T2 second; };
     81 
     82   template<typename T> struct basic_string {
     83     basic_string(const T* x) {}
     84     ~basic_string() {};
     85   };
     86   typedef basic_string<char> string;
     87 
     88 } // std
     89 
     90 namespace dr1579 { // dr1579: 3.9
     91 template<class T>
     92 struct GenericMoveOnly {
     93   GenericMoveOnly();
     94   template<class U> GenericMoveOnly(const GenericMoveOnly<U> &) = delete; // expected-note 5 {{marked deleted here}}
     95   GenericMoveOnly(const int &) = delete; // expected-note 2 {{marked deleted here}}
     96   template<class U> GenericMoveOnly(GenericMoveOnly<U> &&);
     97   GenericMoveOnly(int &&);
     98 };
     99 
    100 GenericMoveOnly<float> DR1579_Eligible(GenericMoveOnly<char> CharMO) {
    101   int i;
    102   GenericMoveOnly<char> GMO;
    103 
    104   if (0)
    105     return i;
    106   else if (0)
    107     return GMO;
    108   else if (0)
    109     return ((GMO));
    110   else
    111     return CharMO;
    112 }
    113 
    114 GenericMoveOnly<char> GlobalMO;
    115 
    116 GenericMoveOnly<float> DR1579_Ineligible(int &AnInt,
    117                                           GenericMoveOnly<char> &CharMO) {
    118   static GenericMoveOnly<char> StaticMove;
    119   extern GenericMoveOnly<char> ExternMove;
    120 
    121   if (0)
    122     return AnInt; // expected-error{{invokes a deleted function}}
    123   else if (0)
    124     return GlobalMO; // expected-error{{invokes a deleted function}}
    125   else if (0)
    126     return StaticMove; // expected-error{{invokes a deleted function}}
    127   else if (0)
    128     return ExternMove; // expected-error{{invokes a deleted function}}
    129   else if (0)
    130     return AnInt; // expected-error{{invokes a deleted function}}
    131   else
    132     return CharMO; // expected-error{{invokes a deleted function}}
    133 }
    134 
    135 auto DR1579_lambda_valid = [](GenericMoveOnly<float> mo) ->
    136   GenericMoveOnly<char> {
    137   return mo;
    138 };
    139 
    140 auto DR1579_lambda_invalid = []() -> GenericMoveOnly<char> {
    141   static GenericMoveOnly<float> mo;
    142   return mo; // expected-error{{invokes a deleted function}}
    143 };
    144 } // end namespace dr1579
    145 
    146 namespace dr1589 {   // dr1589: 3.7 c++11
    147   // Ambiguous ranking of list-initialization sequences
    148 
    149   void f0(long, int=0);                 // Would makes selection of #0 ambiguous
    150   void f0(long);                        // #0
    151   void f0(std::initializer_list<int>);  // #00
    152   void g0() { f0({1L}); }               // chooses #00
    153 
    154   void f1(int, int=0);                    // Would make selection of #1 ambiguous
    155   void f1(int);                           // #1
    156   void f1(std::initializer_list<long>);   // #2
    157   void g1() { f1({42}); }                 // chooses #2
    158 
    159   void f2(std::pair<const char*, const char*>, int = 0); // Would makes selection of #3 ambiguous
    160   void f2(std::pair<const char*, const char*>); // #3
    161   void f2(std::initializer_list<std::string>);  // #4
    162   void g2() { f2({"foo","bar"}); }              // chooses #4
    163 
    164   namespace with_error {
    165     void f0(long);                        // #0    expected-note {{candidate function}}
    166     void f0(std::initializer_list<int>);  // #00   expected-note {{candidate function}}
    167     void f0(std::initializer_list<int>, int = 0);  // Makes selection of #00 ambiguous \
    168     // expected-note {{candidate function}}
    169     void g0() { f0({1L}); }                 // chooses #00    expected-error{{call to 'f0' is ambiguous}}
    170 
    171     void f1(int);                           // #1   expected-note {{candidate function}}
    172     void f1(std::initializer_list<long>);   // #2   expected-note {{candidate function}}
    173     void f1(std::initializer_list<long>, int = 0);   // Makes selection of #00 ambiguous \
    174     // expected-note {{candidate function}}
    175     void g1() { f1({42}); }                 // chooses #2   expected-error{{call to 'f1' is ambiguous}}
    176 
    177     void f2(std::pair<const char*, const char*>); // #3   TODO: expected- note {{candidate function}}
    178     void f2(std::initializer_list<std::string>);  // #4   expected-note {{candidate function}}
    179     void f2(std::initializer_list<std::string>, int = 0);   // Makes selection of #00 ambiguous \
    180     // expected-note {{candidate function}}
    181     void g2() { f2({"foo","bar"}); }        // chooses #4   expected-error{{call to 'f2' is ambiguous}}
    182   }
    183 
    184 } // dr1589
    185 
    186 namespace dr1591 {  //dr1591. Deducing array bound and element type from initializer list
    187   template<class T, int N> int h(T const(&)[N]);
    188   int X = h({1,2,3});              // T deduced to int, N deduced to 3
    189 
    190   template<class T> int j(T const(&)[3]);
    191   int Y = j({42});                 // T deduced to int, array bound not considered
    192 
    193   struct Aggr { int i; int j; };
    194   template<int N> int k(Aggr const(&)[N]); //expected-note{{not viable}}
    195   int Y0 = k({1,2,3});              //expected-error{{no matching function}}
    196   int Z = k({{1},{2},{3}});        // OK, N deduced to 3
    197 
    198   template<int M, int N> int m(int const(&)[M][N]);
    199   int X0 = m({{1,2},{3,4}});        // M and N both deduced to 2
    200 
    201   template<class T, int N> int n(T const(&)[N], T);
    202   int X1 = n({{1},{2},{3}},Aggr()); // OK, T is Aggr, N is 3
    203 
    204 
    205   namespace check_multi_dim_arrays {
    206     template<class T, int N, int M, int O> int ***f(const T (&a)[N][M][O]); //expected-note{{deduced conflicting values}}
    207     template<class T, int N, int M> int **f(const T (&a)[N][M]); //expected-note{{couldn't infer}}
    208 
    209    template<class T, int N> int *f(const T (&a)[N]); //expected-note{{couldn't infer}}
    210     int ***p3 = f({  {  {1,2}, {3, 4}  }, {  {5,6}, {7, 8}  }, {  {9,10}, {11, 12}  } });
    211     int ***p33 = f({  {  {1,2}, {3, 4}  }, {  {5,6}, {7, 8}  }, {  {9,10}, {11, 12, 13}  } }); //expected-error{{no matching}}
    212     int **p2 = f({  {1,2,3}, {3, 4, 5}  });
    213     int **p22 = f({  {1,2}, {3, 4}  });
    214     int *p1 = f({1, 2, 3});
    215   }
    216   namespace check_multi_dim_arrays_rref {
    217     template<class T, int N, int M, int O> int ***f(T (&&a)[N][M][O]); //expected-note{{deduced conflicting values}}
    218     template<class T, int N, int M> int **f(T (&&a)[N][M]); //expected-note{{couldn't infer}}
    219 
    220     template<class T, int N> int *f(T (&&a)[N]); //expected-note{{couldn't infer}}
    221     int ***p3 = f({  {  {1,2}, {3, 4}  }, {  {5,6}, {7, 8}  }, {  {9,10}, {11, 12}  } });
    222     int ***p33 = f({  {  {1,2}, {3, 4}  }, {  {5,6}, {7, 8}  }, {  {9,10}, {11, 12, 13}  } }); //expected-error{{no matching}}
    223     int **p2 = f({  {1,2,3}, {3, 4, 5}  });
    224     int **p22 = f({  {1,2}, {3, 4}  });
    225     int *p1 = f({1, 2, 3});
    226   }
    227 
    228   namespace check_arrays_of_init_list {
    229     template<class T, int N> float *f(const std::initializer_list<T> (&)[N]);
    230     template<class T, int N> double *f(const T(&)[N]);
    231     double *p = f({1, 2, 3});
    232     float *fp = f({{1}, {1, 2}, {1, 2, 3}});
    233   }
    234   namespace core_reflector_28543 {
    235 
    236     template<class T, int N> int *f(T (&&)[N]);  // #1
    237     template<class T> char *f(std::initializer_list<T> &&);  //#2
    238     template<class T, int N, int M> int **f(T (&&)[N][M]); //#3 expected-note{{candidate}}
    239     template<class T, int N> char **f(std::initializer_list<T> (&&)[N]); //#4 expected-note{{candidate}}
    240 
    241     template<class T> short *f(T (&&)[2]);  //#5
    242 
    243     template<class T> using Arr = T[];
    244 
    245     char *pc = f({1, 2, 3}); // OK prefer #2 via 13.3.3.2 [over.ics.rank]
    246     char *pc2 = f({1, 2}); // #2 also
    247     int *pi = f(Arr<int>{1, 2, 3}); // OK prefer #1
    248 
    249     void *pv1 = f({ {1, 2, 3}, {4, 5, 6} }); // expected-error{{ambiguous}} btw 3 & 4
    250     char **pcc = f({ {1}, {2, 3} }); // OK #4
    251 
    252     short *ps = f(Arr<int>{1, 2});  // OK #5
    253   }
    254 } // dr1591
    255 
    256 #endif
    257