overloaded-operator.cpp revision 7a8233a69103a6eeb6602bd4a17fb5d9b7bacaad
1// RUN: clang-cc -fsyntax-only -verify %s 2class X { }; 3 4X operator+(X, X); 5 6void f(X x) { 7 x = x + x; 8} 9 10struct Y; 11struct Z; 12 13struct Y { 14 Y(const Z&); 15}; 16 17struct Z { 18 Z(const Y&); 19}; 20 21Y operator+(Y, Y); 22bool operator-(Y, Y); // expected-note{{candidate function}} 23bool operator-(Z, Z); // expected-note{{candidate function}} 24 25void g(Y y, Z z) { 26 y = y + z; 27 bool b = y - z; // expected-error{{use of overloaded operator '-' is ambiguous; candidates are:}} 28} 29 30struct A { 31 bool operator==(Z&); // expected-note{{candidate function}} 32}; 33 34A make_A(); 35 36bool operator==(A&, Z&); // expected-note{{candidate function}} 37 38void h(A a, const A ac, Z z) { 39 make_A() == z; 40 a == z; // expected-error{{use of overloaded operator '==' is ambiguous; candidates are:}} 41 ac == z; // expected-error{{invalid operands to binary expression ('struct A const' and 'struct Z')}} 42} 43 44struct B { 45 bool operator==(const B&) const; 46 47 void test(Z z) { 48 make_A() == z; 49 } 50}; 51 52enum Enum1 { }; 53enum Enum2 { }; 54 55struct E1 { 56 E1(Enum1) { } 57}; 58 59struct E2 { 60 E2(Enum2); 61}; 62 63// C++ [over.match.oper]p3 - enum restriction. 64float& operator==(E1, E2); 65 66void enum_test(Enum1 enum1, Enum2 enum2, E1 e1, E2 e2) { 67 float &f1 = (e1 == e2); 68 float &f2 = (enum1 == e2); 69 float &f3 = (e1 == enum2); 70 float &f4 = (enum1 == enum2); // expected-error{{non-const lvalue reference to type 'float' cannot be initialized with a temporary of type 'bool'}} 71} 72 73 74struct PostInc { 75 PostInc operator++(int); 76 PostInc& operator++(); 77}; 78 79struct PostDec { 80 PostDec operator--(int); 81 PostDec& operator--(); 82}; 83 84void incdec_test(PostInc pi, PostDec pd) { 85 const PostInc& pi1 = pi++; 86 const PostDec& pd1 = pd--; 87 PostInc &pi2 = ++pi; 88 PostDec &pd2 = --pd; 89} 90 91struct SmartPtr { 92 int& operator*(); 93 long& operator*() const volatile; 94}; 95 96void test_smartptr(SmartPtr ptr, const SmartPtr cptr, 97 const volatile SmartPtr cvptr) { 98 int &ir = *ptr; 99 long &lr = *cptr; 100 long &lr2 = *cvptr; 101} 102 103 104struct ArrayLike { 105 int& operator[](int); 106}; 107 108void test_arraylike(ArrayLike a) { 109 int& ir = a[17]; 110} 111 112struct SmartRef { 113 int* operator&(); 114}; 115 116void test_smartref(SmartRef r) { 117 int* ip = &r; 118} 119 120bool& operator,(X, Y); 121 122void test_comma(X x, Y y) { 123 bool& b1 = (x, y); 124 X& xr = (x, x); 125} 126 127struct Callable { 128 int& operator()(int, double = 2.71828); // expected-note{{candidate function}} 129 float& operator()(int, double, long, ...); // expected-note{{candidate function}} 130 131 double& operator()(float); // expected-note{{candidate function}} 132}; 133 134struct Callable2 { 135 int& operator()(int i = 0); 136 double& operator()(...) const; 137}; 138 139void test_callable(Callable c, Callable2 c2, const Callable2& c2c) { 140 int &ir = c(1); 141 float &fr = c(1, 3.14159, 17, 42); 142 143 c(); // expected-error{{no matching function for call to object of type 'struct Callable'; candidates are:}} 144 145 double &dr = c(1.0f); 146 147 int &ir2 = c2(); 148 int &ir3 = c2(1); 149 double &fr2 = c2c(); 150} 151 152typedef float FLOAT; 153typedef int& INTREF; 154typedef INTREF Func1(FLOAT, double); 155typedef float& Func2(int, double); 156 157struct ConvertToFunc { 158 operator Func1*(); // expected-note{{conversion candidate of type 'INTREF (*)(float, double)'}} 159 operator Func2&(); // expected-note{{conversion candidate of type 'float &(&)(int, double)'}} 160 void operator()(); 161}; 162 163void test_funcptr_call(ConvertToFunc ctf) { 164 int &i1 = ctf(1.0f, 2.0); 165 float &f2 = ctf((short int)1, 1.0f); 166 ctf((long int)17, 2.0); // expected-error{{error: call to object of type 'struct ConvertToFunc' is ambiguous; candidates are:}} 167 ctf(); 168} 169 170struct HasMember { 171 int m; 172}; 173 174struct Arrow1 { 175 HasMember* operator->(); 176}; 177 178struct Arrow2 { 179 Arrow1 operator->(); // expected-note{{candidate function}} 180}; 181 182void test_arrow(Arrow1 a1, Arrow2 a2, const Arrow2 a3) { 183 int &i1 = a1->m; 184 int &i2 = a2->m; 185 a3->m; // expected-error{{no viable overloaded 'operator->'; candidate is}} 186} 187 188struct CopyConBase { 189}; 190 191struct CopyCon : public CopyConBase { 192 CopyCon(const CopyConBase &Base); 193 194 CopyCon(const CopyConBase *Base) { 195 *this = *Base; 196 } 197}; 198 199namespace N { 200 struct X { }; 201} 202 203namespace M { 204 N::X operator+(N::X, N::X); 205} 206 207namespace M { 208 void test_X(N::X x) { 209 (void)(x + x); 210 } 211} 212 213struct AA { bool operator!=(AA&); }; 214struct BB : AA {}; 215bool x(BB y, BB z) { return y != z; } 216 217 218struct AX { 219 AX& operator ->(); // expected-note {{declared at}} 220 int b; 221}; 222 223void m() { 224 AX a; 225 a->b = 0; // expected-error {{circular pointer delegation detected}} 226} 227 228struct CircA { 229 struct CircB& operator->(); // expected-note {{declared at}} 230 int val; 231}; 232struct CircB { 233 struct CircC& operator->(); // expected-note {{declared at}} 234}; 235struct CircC { 236 struct CircA& operator->(); // expected-note {{declared at}} 237}; 238 239void circ() { 240 CircA a; 241 a->val = 0; // expected-error {{circular pointer delegation detected}} 242} 243