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