xref: /aosp_15_r20/external/clang/test/SemaCXX/overloaded-operator.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2*67e74705SXin Li class X { };
3*67e74705SXin Li 
4*67e74705SXin Li X operator+(X, X);
5*67e74705SXin Li 
f(X x)6*67e74705SXin Li void f(X x) {
7*67e74705SXin Li   x = x + x;
8*67e74705SXin Li }
9*67e74705SXin Li 
10*67e74705SXin Li struct Y;
11*67e74705SXin Li struct Z;
12*67e74705SXin Li 
13*67e74705SXin Li struct Y {
14*67e74705SXin Li   Y(const Z&);
15*67e74705SXin Li };
16*67e74705SXin Li 
17*67e74705SXin Li struct Z {
18*67e74705SXin Li   Z(const Y&);
19*67e74705SXin Li };
20*67e74705SXin Li 
21*67e74705SXin Li Y operator+(Y, Y);
22*67e74705SXin Li bool operator-(Y, Y); // expected-note{{candidate function}}
23*67e74705SXin Li bool operator-(Z, Z); // expected-note{{candidate function}}
24*67e74705SXin Li 
g(Y y,Z z)25*67e74705SXin Li void g(Y y, Z z) {
26*67e74705SXin Li   y = y + z;
27*67e74705SXin Li   bool b = y - z; // expected-error{{use of overloaded operator '-' is ambiguous}}
28*67e74705SXin Li }
29*67e74705SXin Li 
30*67e74705SXin Li struct A {
31*67e74705SXin Li   bool operator==(Z&); // expected-note 2{{candidate function}}
32*67e74705SXin Li };
33*67e74705SXin Li 
34*67e74705SXin Li A make_A();
35*67e74705SXin Li 
36*67e74705SXin Li bool operator==(A&, Z&); // expected-note 3{{candidate function}}
37*67e74705SXin Li 
h(A a,const A ac,Z z)38*67e74705SXin Li void h(A a, const A ac, Z z) {
39*67e74705SXin Li   make_A() == z; // expected-warning{{equality comparison result unused}}
40*67e74705SXin Li   a == z; // expected-error{{use of overloaded operator '==' is ambiguous}}
41*67e74705SXin Li   ac == z; // expected-error{{invalid operands to binary expression ('const A' and 'Z')}}
42*67e74705SXin Li }
43*67e74705SXin Li 
44*67e74705SXin Li struct B {
45*67e74705SXin Li   bool operator==(const B&) const;
46*67e74705SXin Li 
testB47*67e74705SXin Li   void test(Z z) {
48*67e74705SXin Li     make_A() == z; // expected-warning{{equality comparison result unused}}
49*67e74705SXin Li   }
50*67e74705SXin Li };
51*67e74705SXin Li 
52*67e74705SXin Li // we shouldn't see warnings about self-comparison,
53*67e74705SXin Li // this is a member function, we dunno what it'll do
i(B b)54*67e74705SXin Li bool i(B b)
55*67e74705SXin Li {
56*67e74705SXin Li   return b == b;
57*67e74705SXin Li }
58*67e74705SXin Li 
59*67e74705SXin Li enum Enum1 { };
60*67e74705SXin Li enum Enum2 { };
61*67e74705SXin Li 
62*67e74705SXin Li struct E1 {
E1E163*67e74705SXin Li   E1(Enum1) { }
64*67e74705SXin Li };
65*67e74705SXin Li 
66*67e74705SXin Li struct E2 {
67*67e74705SXin Li   E2(Enum2);
68*67e74705SXin Li };
69*67e74705SXin Li 
70*67e74705SXin Li // C++ [over.match.oper]p3 - enum restriction.
71*67e74705SXin Li float& operator==(E1, E2);  // expected-note{{candidate function}}
72*67e74705SXin Li 
enum_test(Enum1 enum1,Enum2 enum2,E1 e1,E2 e2,Enum1 next_enum1)73*67e74705SXin Li void enum_test(Enum1 enum1, Enum2 enum2, E1 e1, E2 e2, Enum1 next_enum1) {
74*67e74705SXin Li   float &f1 = (e1 == e2);
75*67e74705SXin Li   float &f2 = (enum1 == e2);
76*67e74705SXin Li   float &f3 = (e1 == enum2);
77*67e74705SXin Li   float &f4 = (enum1 == next_enum1);  // expected-error{{non-const lvalue reference to type 'float' cannot bind to a temporary of type 'bool'}}
78*67e74705SXin Li }
79*67e74705SXin Li 
80*67e74705SXin Li // PR5244 - Argument-dependent lookup would include the two operators below,
81*67e74705SXin Li // which would break later assumptions and lead to a crash.
82*67e74705SXin Li class pr5244_foo
83*67e74705SXin Li {
84*67e74705SXin Li   pr5244_foo(int);
85*67e74705SXin Li   pr5244_foo(char);
86*67e74705SXin Li };
87*67e74705SXin Li 
88*67e74705SXin Li bool operator==(const pr5244_foo& s1, const pr5244_foo& s2); // expected-note{{candidate function}}
89*67e74705SXin Li bool operator==(char c, const pr5244_foo& s); // expected-note{{candidate function}}
90*67e74705SXin Li 
91*67e74705SXin Li enum pr5244_bar
92*67e74705SXin Li {
93*67e74705SXin Li     pr5244_BAR
94*67e74705SXin Li };
95*67e74705SXin Li 
96*67e74705SXin Li class pr5244_baz
97*67e74705SXin Li {
98*67e74705SXin Li public:
99*67e74705SXin Li     pr5244_bar quux;
100*67e74705SXin Li };
101*67e74705SXin Li 
pr5244_barbaz()102*67e74705SXin Li void pr5244_barbaz()
103*67e74705SXin Li {
104*67e74705SXin Li   pr5244_baz quuux;
105*67e74705SXin Li   (void)(pr5244_BAR == quuux.quux);
106*67e74705SXin Li }
107*67e74705SXin Li 
108*67e74705SXin Li 
109*67e74705SXin Li 
110*67e74705SXin Li struct PostInc {
111*67e74705SXin Li   PostInc operator++(int);
112*67e74705SXin Li   PostInc& operator++();
113*67e74705SXin Li };
114*67e74705SXin Li 
115*67e74705SXin Li struct PostDec {
116*67e74705SXin Li   PostDec operator--(int);
117*67e74705SXin Li   PostDec& operator--();
118*67e74705SXin Li };
119*67e74705SXin Li 
incdec_test(PostInc pi,PostDec pd)120*67e74705SXin Li void incdec_test(PostInc pi, PostDec pd) {
121*67e74705SXin Li   const PostInc& pi1 = pi++;
122*67e74705SXin Li   const PostDec& pd1 = pd--;
123*67e74705SXin Li   PostInc &pi2 = ++pi;
124*67e74705SXin Li   PostDec &pd2 = --pd;
125*67e74705SXin Li }
126*67e74705SXin Li 
127*67e74705SXin Li struct SmartPtr {
128*67e74705SXin Li   int& operator*();
129*67e74705SXin Li   long& operator*() const volatile;
130*67e74705SXin Li };
131*67e74705SXin Li 
test_smartptr(SmartPtr ptr,const SmartPtr cptr,const volatile SmartPtr cvptr)132*67e74705SXin Li void test_smartptr(SmartPtr ptr, const SmartPtr cptr,
133*67e74705SXin Li                    const volatile SmartPtr cvptr) {
134*67e74705SXin Li   int &ir = *ptr;
135*67e74705SXin Li   long &lr = *cptr;
136*67e74705SXin Li   long &lr2 = *cvptr;
137*67e74705SXin Li }
138*67e74705SXin Li 
139*67e74705SXin Li 
140*67e74705SXin Li struct ArrayLike {
141*67e74705SXin Li   int& operator[](int);
142*67e74705SXin Li };
143*67e74705SXin Li 
test_arraylike(ArrayLike a)144*67e74705SXin Li void test_arraylike(ArrayLike a) {
145*67e74705SXin Li   int& ir = a[17];
146*67e74705SXin Li }
147*67e74705SXin Li 
148*67e74705SXin Li struct SmartRef {
149*67e74705SXin Li   int* operator&();
150*67e74705SXin Li };
151*67e74705SXin Li 
test_smartref(SmartRef r)152*67e74705SXin Li void test_smartref(SmartRef r) {
153*67e74705SXin Li   int* ip = &r;
154*67e74705SXin Li }
155*67e74705SXin Li 
156*67e74705SXin Li bool& operator,(X, Y);
157*67e74705SXin Li 
test_comma(X x,Y y)158*67e74705SXin Li void test_comma(X x, Y y) {
159*67e74705SXin Li   bool& b1 = (x, y);
160*67e74705SXin Li   X& xr = (x, x); // expected-warning {{expression result unused}}
161*67e74705SXin Li }
162*67e74705SXin Li 
163*67e74705SXin Li struct Callable {
164*67e74705SXin Li   int& operator()(int, double = 2.71828); // expected-note{{candidate function}}
165*67e74705SXin Li   float& operator()(int, double, long, ...); // expected-note{{candidate function}}
166*67e74705SXin Li 
167*67e74705SXin Li   double& operator()(float); // expected-note{{candidate function}}
168*67e74705SXin Li };
169*67e74705SXin Li 
170*67e74705SXin Li struct Callable2 {
171*67e74705SXin Li   int& operator()(int i = 0);
172*67e74705SXin Li   double& operator()(...) const;
173*67e74705SXin Li };
174*67e74705SXin Li 
175*67e74705SXin Li struct DerivesCallable : public Callable {
176*67e74705SXin Li };
177*67e74705SXin Li 
test_callable(Callable c,Callable2 c2,const Callable2 & c2c,DerivesCallable dc)178*67e74705SXin Li void test_callable(Callable c, Callable2 c2, const Callable2& c2c,
179*67e74705SXin Li                    DerivesCallable dc) {
180*67e74705SXin Li   int &ir = c(1);
181*67e74705SXin Li   float &fr = c(1, 3.14159, 17, 42);
182*67e74705SXin Li 
183*67e74705SXin Li   c(); // expected-error{{no matching function for call to object of type 'Callable'}}
184*67e74705SXin Li 
185*67e74705SXin Li   double &dr = c(1.0f);
186*67e74705SXin Li 
187*67e74705SXin Li   int &ir2 = c2();
188*67e74705SXin Li   int &ir3 = c2(1);
189*67e74705SXin Li   double &fr2 = c2c();
190*67e74705SXin Li 
191*67e74705SXin Li   int &ir4 = dc(17);
192*67e74705SXin Li   double &fr3 = dc(3.14159f);
193*67e74705SXin Li }
194*67e74705SXin Li 
195*67e74705SXin Li typedef float FLOAT;
196*67e74705SXin Li typedef int& INTREF;
197*67e74705SXin Li typedef INTREF Func1(FLOAT, double);
198*67e74705SXin Li typedef float& Func2(int, double);
199*67e74705SXin Li 
200*67e74705SXin Li struct ConvertToFunc {
201*67e74705SXin Li   operator Func1*(); // expected-note 2{{conversion candidate of type 'INTREF (*)(FLOAT, double)'}}
202*67e74705SXin Li   operator Func2&(); // expected-note 2{{conversion candidate of type 'float &(&)(int, double)'}}
203*67e74705SXin Li   void operator()();
204*67e74705SXin Li };
205*67e74705SXin Li 
206*67e74705SXin Li struct ConvertToFuncDerived : ConvertToFunc { };
207*67e74705SXin Li 
test_funcptr_call(ConvertToFunc ctf,ConvertToFuncDerived ctfd)208*67e74705SXin Li void test_funcptr_call(ConvertToFunc ctf, ConvertToFuncDerived ctfd) {
209*67e74705SXin Li   int &i1 = ctf(1.0f, 2.0);
210*67e74705SXin Li   float &f1 = ctf((short int)1, 1.0f);
211*67e74705SXin Li   ctf((long int)17, 2.0); // expected-error{{call to object of type 'ConvertToFunc' is ambiguous}}
212*67e74705SXin Li   ctf();
213*67e74705SXin Li 
214*67e74705SXin Li   int &i2 = ctfd(1.0f, 2.0);
215*67e74705SXin Li   float &f2 = ctfd((short int)1, 1.0f);
216*67e74705SXin Li   ctfd((long int)17, 2.0); // expected-error{{call to object of type 'ConvertToFuncDerived' is ambiguous}}
217*67e74705SXin Li   ctfd();
218*67e74705SXin Li }
219*67e74705SXin Li 
220*67e74705SXin Li struct HasMember {
221*67e74705SXin Li   int m;
222*67e74705SXin Li };
223*67e74705SXin Li 
224*67e74705SXin Li struct Arrow1 {
225*67e74705SXin Li   HasMember* operator->();
226*67e74705SXin Li };
227*67e74705SXin Li 
228*67e74705SXin Li struct Arrow2 {
229*67e74705SXin Li   Arrow1 operator->(); // expected-note{{candidate function}}
230*67e74705SXin Li };
231*67e74705SXin Li 
test_arrow(Arrow1 a1,Arrow2 a2,const Arrow2 a3)232*67e74705SXin Li void test_arrow(Arrow1 a1, Arrow2 a2, const Arrow2 a3) {
233*67e74705SXin Li   int &i1 = a1->m;
234*67e74705SXin Li   int &i2 = a2->m;
235*67e74705SXin Li   a3->m; // expected-error{{no viable overloaded 'operator->'}}
236*67e74705SXin Li }
237*67e74705SXin Li 
238*67e74705SXin Li struct CopyConBase {
239*67e74705SXin Li };
240*67e74705SXin Li 
241*67e74705SXin Li struct CopyCon : public CopyConBase {
242*67e74705SXin Li   CopyCon(const CopyConBase &Base);
243*67e74705SXin Li 
CopyConCopyCon244*67e74705SXin Li   CopyCon(const CopyConBase *Base) {
245*67e74705SXin Li     *this = *Base;
246*67e74705SXin Li   }
247*67e74705SXin Li };
248*67e74705SXin Li 
249*67e74705SXin Li namespace N {
250*67e74705SXin Li   struct X { };
251*67e74705SXin Li }
252*67e74705SXin Li 
253*67e74705SXin Li namespace M {
254*67e74705SXin Li   N::X operator+(N::X, N::X);
255*67e74705SXin Li }
256*67e74705SXin Li 
257*67e74705SXin Li namespace M {
test_X(N::X x)258*67e74705SXin Li   void test_X(N::X x) {
259*67e74705SXin Li     (void)(x + x);
260*67e74705SXin Li   }
261*67e74705SXin Li }
262*67e74705SXin Li 
263*67e74705SXin Li struct AA { bool operator!=(AA&); };
264*67e74705SXin Li struct BB : AA {};
x(BB y,BB z)265*67e74705SXin Li bool x(BB y, BB z) { return y != z; }
266*67e74705SXin Li 
267*67e74705SXin Li 
268*67e74705SXin Li struct AX {
269*67e74705SXin Li   AX& operator ->();	 // expected-note {{declared here}}
270*67e74705SXin Li   int b;
271*67e74705SXin Li };
272*67e74705SXin Li 
m()273*67e74705SXin Li void m() {
274*67e74705SXin Li   AX a;
275*67e74705SXin Li   a->b = 0; // expected-error {{circular pointer delegation detected}}
276*67e74705SXin Li }
277*67e74705SXin Li 
278*67e74705SXin Li struct CircA {
279*67e74705SXin Li   struct CircB& operator->(); // expected-note {{declared here}}
280*67e74705SXin Li   int val;
281*67e74705SXin Li };
282*67e74705SXin Li struct CircB {
283*67e74705SXin Li   struct CircC& operator->(); // expected-note {{declared here}}
284*67e74705SXin Li };
285*67e74705SXin Li struct CircC {
286*67e74705SXin Li   struct CircA& operator->(); // expected-note {{declared here}}
287*67e74705SXin Li };
288*67e74705SXin Li 
circ()289*67e74705SXin Li void circ() {
290*67e74705SXin Li   CircA a;
291*67e74705SXin Li   a->val = 0; // expected-error {{circular pointer delegation detected}}
292*67e74705SXin Li }
293*67e74705SXin Li 
294*67e74705SXin Li // PR5360: Arrays should lead to built-in candidates for subscript.
295*67e74705SXin Li typedef enum {
296*67e74705SXin Li   LastReg = 23,
297*67e74705SXin Li } Register;
298*67e74705SXin Li class RegAlloc {
getPriority(Register r)299*67e74705SXin Li   int getPriority(Register r) {
300*67e74705SXin Li     return usepri[r];
301*67e74705SXin Li   }
302*67e74705SXin Li   int usepri[LastReg + 1];
303*67e74705SXin Li };
304*67e74705SXin Li 
305*67e74705SXin Li // PR5546: Don't generate incorrect and ambiguous overloads for multi-level
306*67e74705SXin Li // arrays.
307*67e74705SXin Li namespace pr5546
308*67e74705SXin Li {
309*67e74705SXin Li   enum { X };
310*67e74705SXin Li   extern const char *const sMoveCommands[][2][2];
a()311*67e74705SXin Li   const char* a() { return sMoveCommands[X][0][0]; }
b()312*67e74705SXin Li   const char* b() { return (*(sMoveCommands+X))[0][0]; }
313*67e74705SXin Li }
314*67e74705SXin Li 
315*67e74705SXin Li // PR5512 and its discussion
316*67e74705SXin Li namespace pr5512 {
317*67e74705SXin Li   struct Y {
318*67e74705SXin Li     operator short();
319*67e74705SXin Li     operator float();
320*67e74705SXin Li   };
g_test(Y y)321*67e74705SXin Li   void g_test(Y y) {
322*67e74705SXin Li     short s = 0;
323*67e74705SXin Li     // DR507, this should be ambiguous, but we special-case assignment
324*67e74705SXin Li     s = y;
325*67e74705SXin Li     // Note: DR507, this is ambiguous as specified
326*67e74705SXin Li     //s += y;
327*67e74705SXin Li   }
328*67e74705SXin Li 
329*67e74705SXin Li   struct S {};
330*67e74705SXin Li   void operator +=(int&, S);
f(S s)331*67e74705SXin Li   void f(S s) {
332*67e74705SXin Li     int i = 0;
333*67e74705SXin Li     i += s;
334*67e74705SXin Li   }
335*67e74705SXin Li 
336*67e74705SXin Li   struct A {operator int();};
337*67e74705SXin Li   int a;
b(A x)338*67e74705SXin Li   void b(A x) {
339*67e74705SXin Li     a += x;
340*67e74705SXin Li   }
341*67e74705SXin Li }
342*67e74705SXin Li 
343*67e74705SXin Li // PR5900
344*67e74705SXin Li namespace pr5900 {
345*67e74705SXin Li   struct NotAnArray {};
test0()346*67e74705SXin Li   void test0() {
347*67e74705SXin Li     NotAnArray x;
348*67e74705SXin Li     x[0] = 0; // expected-error {{does not provide a subscript operator}}
349*67e74705SXin Li   }
350*67e74705SXin Li 
351*67e74705SXin Li   struct NonConstArray {
352*67e74705SXin Li     int operator[](unsigned); // expected-note {{candidate}}
353*67e74705SXin Li   };
test1()354*67e74705SXin Li   int test1() {
355*67e74705SXin Li     const NonConstArray x = NonConstArray();
356*67e74705SXin Li     return x[0]; // expected-error {{no viable overloaded operator[] for type}}
357*67e74705SXin Li   }
358*67e74705SXin Li 
359*67e74705SXin Li   // Not really part of this PR, but implemented at the same time.
360*67e74705SXin Li   struct NotAFunction {};
test2()361*67e74705SXin Li   void test2() {
362*67e74705SXin Li     NotAFunction x;
363*67e74705SXin Li     x(); // expected-error {{does not provide a call operator}}
364*67e74705SXin Li   }
365*67e74705SXin Li }
366*67e74705SXin Li 
367*67e74705SXin Li // Operator lookup through using declarations.
368*67e74705SXin Li namespace N {
369*67e74705SXin Li   struct X2 { };
370*67e74705SXin Li }
371*67e74705SXin Li 
372*67e74705SXin Li namespace N2 {
373*67e74705SXin Li   namespace M {
374*67e74705SXin Li     namespace Inner {
375*67e74705SXin Li       template<typename T>
376*67e74705SXin Li       N::X2 &operator<<(N::X2&, const T&);
377*67e74705SXin Li     }
378*67e74705SXin Li     using Inner::operator<<;
379*67e74705SXin Li   }
380*67e74705SXin Li }
381*67e74705SXin Li 
test_lookup_through_using()382*67e74705SXin Li void test_lookup_through_using() {
383*67e74705SXin Li   using namespace N2::M;
384*67e74705SXin Li   N::X2 x;
385*67e74705SXin Li   x << 17;
386*67e74705SXin Li }
387*67e74705SXin Li 
388*67e74705SXin Li namespace rdar9136502 {
389*67e74705SXin Li   struct X {
390*67e74705SXin Li     int i(); // expected-note{{possible target for call}}
391*67e74705SXin Li     int i(int); // expected-note{{possible target for call}}
392*67e74705SXin Li   };
393*67e74705SXin Li 
394*67e74705SXin Li   struct Y {
395*67e74705SXin Li     Y &operator<<(int);
396*67e74705SXin Li   };
397*67e74705SXin Li 
f(X x,Y y)398*67e74705SXin Li   void f(X x, Y y) {
399*67e74705SXin Li     y << x
400*67e74705SXin Li       .i; // expected-error{{reference to non-static member function must be called; did you mean to call it with no arguments?}}
401*67e74705SXin Li   }
402*67e74705SXin Li }
403*67e74705SXin Li 
404*67e74705SXin Li namespace rdar9222009 {
405*67e74705SXin Li class StringRef {
operator ==(StringRef LHS,StringRef RHS)406*67e74705SXin Li   inline bool operator==(StringRef LHS, StringRef RHS) { // expected-error{{overloaded 'operator==' must be a binary operator (has 3 parameters)}}
407*67e74705SXin Li     return !(LHS == RHS); // expected-error{{invalid operands to binary expression ('rdar9222009::StringRef' and 'rdar9222009::StringRef')}}
408*67e74705SXin Li   }
409*67e74705SXin Li };
410*67e74705SXin Li 
411*67e74705SXin Li }
412*67e74705SXin Li 
413*67e74705SXin Li namespace PR11784 {
414*67e74705SXin Li   struct A { A& operator=(void (*x)()); };
415*67e74705SXin Li   void f();
416*67e74705SXin Li   void f(int);
g()417*67e74705SXin Li   void g() { A x; x = f; }
418*67e74705SXin Li }
419*67e74705SXin Li 
420*67e74705SXin Li namespace test10 {
421*67e74705SXin Li   struct A {
422*67e74705SXin Li     void operator[](float (*fn)(int)); // expected-note 2 {{not viable: no overload of 'bar' matching 'float (*)(int)'}}
423*67e74705SXin Li   };
424*67e74705SXin Li 
425*67e74705SXin Li   float foo(int);
426*67e74705SXin Li   float foo(float);
427*67e74705SXin Li 
428*67e74705SXin Li   template <class T> T bar(T);
429*67e74705SXin Li   template <class T, class U> T bar(U);
430*67e74705SXin Li 
test(A & a)431*67e74705SXin Li   void test(A &a) {
432*67e74705SXin Li     a[&foo];
433*67e74705SXin Li     a[foo];
434*67e74705SXin Li 
435*67e74705SXin Li     a[&bar<int>]; // expected-error {{no viable overloaded operator[]}}
436*67e74705SXin Li     a[bar<int>]; // expected-error {{no viable overloaded operator[]}}
437*67e74705SXin Li 
438*67e74705SXin Li     // If these fail, it's because we're not letting the overload
439*67e74705SXin Li     // resolution for operator| resolve the overload of 'bar'.
440*67e74705SXin Li     a[&bar<float>];
441*67e74705SXin Li     a[bar<float>];
442*67e74705SXin Li   }
443*67e74705SXin Li }
444*67e74705SXin Li 
445*67e74705SXin Li struct InvalidOperatorEquals {
446*67e74705SXin Li   InvalidOperatorEquals operator=() = delete; // expected-error {{overloaded 'operator=' must be a binary operator}}
447*67e74705SXin Li };
448*67e74705SXin Li 
449*67e74705SXin Li namespace PR7681 {
450*67e74705SXin Li   template <typename PT1, typename PT2> class PointerUnion;
foo(PointerUnion<int *,float * > & Result)451*67e74705SXin Li   void foo(PointerUnion<int*, float*> &Result) {
452*67e74705SXin Li     Result = 1; // expected-error {{no viable overloaded '='}} // expected-note {{type 'PointerUnion<int *, float *>' is incomplete}}
453*67e74705SXin Li   }
454*67e74705SXin Li }
455*67e74705SXin Li 
456*67e74705SXin Li namespace PR14995 {
457*67e74705SXin Li   struct B {};
operator ++(B,T...)458*67e74705SXin Li   template<typename ...T> void operator++(B, T...) {}
459*67e74705SXin Li 
f()460*67e74705SXin Li   void f() {
461*67e74705SXin Li     B b;
462*67e74705SXin Li     b++;  // ok
463*67e74705SXin Li     ++b;  // ok
464*67e74705SXin Li   }
465*67e74705SXin Li 
466*67e74705SXin Li   template<typename... T>
467*67e74705SXin Li   struct C {
operator --PR14995::C468*67e74705SXin Li     void operator-- (T...) {}
469*67e74705SXin Li   };
470*67e74705SXin Li 
g()471*67e74705SXin Li   void g() {
472*67e74705SXin Li     C<int> postfix;
473*67e74705SXin Li     C<> prefix;
474*67e74705SXin Li     postfix--;  // ok
475*67e74705SXin Li     --prefix;  // ok
476*67e74705SXin Li   }
477*67e74705SXin Li 
478*67e74705SXin Li   struct D {};
operator ++(D,T)479*67e74705SXin Li   template<typename T> void operator++(D, T) {}
480*67e74705SXin Li 
h()481*67e74705SXin Li   void h() {
482*67e74705SXin Li     D d;
483*67e74705SXin Li     d++;  // ok
484*67e74705SXin Li     ++d; // expected-error{{cannot increment value of type 'PR14995::D'}}
485*67e74705SXin Li   }
486*67e74705SXin Li 
487*67e74705SXin Li   template<typename...T> struct E {
operator ++PR14995::E488*67e74705SXin Li     void operator++(T...) {} // expected-error{{parameter of overloaded post-increment operator must have type 'int' (not 'char')}}
489*67e74705SXin Li   };
490*67e74705SXin Li 
491*67e74705SXin Li   E<char> e; // expected-note {{in instantiation of template class 'PR14995::E<char>' requested here}}
492*67e74705SXin Li 
493*67e74705SXin Li   struct F {
494*67e74705SXin Li     template<typename... T>
operator ++PR14995::F495*67e74705SXin Li     int operator++ (T...) {}
496*67e74705SXin Li   };
497*67e74705SXin Li 
498*67e74705SXin Li   int k1 = F().operator++(0, 0);
499*67e74705SXin Li   int k2 = F().operator++('0');
500*67e74705SXin Li   // expected-error@-5 {{overloaded 'operator++' must be a unary or binary operator}}
501*67e74705SXin Li   // expected-note@-3 {{in instantiation of function template specialization 'PR14995::F::operator++<int, int>' requested here}}
502*67e74705SXin Li   // expected-error@-4 {{no matching member function for call to 'operator++'}}
503*67e74705SXin Li   // expected-note@-8 {{candidate template ignored: substitution failure}}
504*67e74705SXin Li   // expected-error@-9 {{parameter of overloaded post-increment operator must have type 'int' (not 'char')}}
505*67e74705SXin Li   // expected-note@-6 {{in instantiation of function template specialization 'PR14995::F::operator++<char>' requested here}}
506*67e74705SXin Li   // expected-error@-7 {{no matching member function for call to 'operator++'}}
507*67e74705SXin Li   // expected-note@-12 {{candidate template ignored: substitution failure}}
508*67e74705SXin Li } // namespace PR14995
509*67e74705SXin Li 
510*67e74705SXin Li namespace ConversionVersusTemplateOrdering {
511*67e74705SXin Li   struct A {
512*67e74705SXin Li     operator short() = delete;
513*67e74705SXin Li     template <typename T> operator T();
514*67e74705SXin Li   } a;
515*67e74705SXin Li   struct B {
516*67e74705SXin Li     template <typename T> operator T();
517*67e74705SXin Li     operator short() = delete;
518*67e74705SXin Li   } b;
519*67e74705SXin Li   int x = a;
520*67e74705SXin Li   int y = b;
521*67e74705SXin Li }
522*67e74705SXin Li 
523*67e74705SXin Li namespace NoADLForMemberOnlyOperators {
524*67e74705SXin Li   template<typename T> struct A { typename T::error e; }; // expected-error {{type 'char' cannot be used prior to '::'}}
525*67e74705SXin Li   template<typename T> struct B { int n; };
526*67e74705SXin Li 
f(B<A<void>> b1,B<A<int>> b2,B<A<char>> b3)527*67e74705SXin Li   void f(B<A<void> > b1, B<A<int> > b2, B<A<char> > b3) {
528*67e74705SXin Li     b1 = b1; // ok, does not instantiate A<void>.
529*67e74705SXin Li     (void)b1->n; // expected-error {{is not a pointer}}
530*67e74705SXin Li     b2[3]; // expected-error {{does not provide a subscript}}
531*67e74705SXin Li     b3 / 0; // expected-note {{in instantiation of}} expected-error {{invalid operands to}}
532*67e74705SXin Li   }
533*67e74705SXin Li }
534