overloaded-operator.cpp revision 20093b4bf698f292c664676987541d5103b65b15
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 2{{candidate function}} 32}; 33 34A make_A(); 35 36bool operator==(A&, Z&); // expected-note 2{{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 bind to a temporary of type 'bool'}} 71} 72 73// PR5244 - Argument-dependent lookup would include the two operators below, 74// which would break later assumptions and lead to a crash. 75class pr5244_foo 76{ 77 pr5244_foo(int); 78 pr5244_foo(char); 79}; 80 81bool operator==(const pr5244_foo& s1, const pr5244_foo& s2); 82bool operator==(char c, const pr5244_foo& s); 83 84enum pr5244_bar 85{ 86 pr5244_BAR 87}; 88 89class pr5244_baz 90{ 91 pr5244_bar quux; 92}; 93 94void pr5244_barbaz() 95{ 96 pr5244_baz quuux; 97 (void)(pr5244_BAR == quuux.quux); 98} 99 100 101 102struct PostInc { 103 PostInc operator++(int); 104 PostInc& operator++(); 105}; 106 107struct PostDec { 108 PostDec operator--(int); 109 PostDec& operator--(); 110}; 111 112void incdec_test(PostInc pi, PostDec pd) { 113 const PostInc& pi1 = pi++; 114 const PostDec& pd1 = pd--; 115 PostInc &pi2 = ++pi; 116 PostDec &pd2 = --pd; 117} 118 119struct SmartPtr { 120 int& operator*(); 121 long& operator*() const volatile; 122}; 123 124void test_smartptr(SmartPtr ptr, const SmartPtr cptr, 125 const volatile SmartPtr cvptr) { 126 int &ir = *ptr; 127 long &lr = *cptr; 128 long &lr2 = *cvptr; 129} 130 131 132struct ArrayLike { 133 int& operator[](int); 134}; 135 136void test_arraylike(ArrayLike a) { 137 int& ir = a[17]; 138} 139 140struct SmartRef { 141 int* operator&(); 142}; 143 144void test_smartref(SmartRef r) { 145 int* ip = &r; 146} 147 148bool& operator,(X, Y); 149 150void test_comma(X x, Y y) { 151 bool& b1 = (x, y); 152 X& xr = (x, x); 153} 154 155struct Callable { 156 int& operator()(int, double = 2.71828); // expected-note{{candidate function}} 157 float& operator()(int, double, long, ...); // expected-note{{candidate function}} 158 159 double& operator()(float); // expected-note{{candidate function}} 160}; 161 162struct Callable2 { 163 int& operator()(int i = 0); 164 double& operator()(...) const; 165}; 166 167struct DerivesCallable : public Callable { 168}; 169 170void test_callable(Callable c, Callable2 c2, const Callable2& c2c, 171 DerivesCallable dc) { 172 int &ir = c(1); 173 float &fr = c(1, 3.14159, 17, 42); 174 175 c(); // expected-error{{no matching function for call to object of type 'struct Callable'; candidates are:}} 176 177 double &dr = c(1.0f); 178 179 int &ir2 = c2(); 180 int &ir3 = c2(1); 181 double &fr2 = c2c(); 182 183 int &ir4 = dc(17); 184 double &fr3 = dc(3.14159f); 185} 186 187typedef float FLOAT; 188typedef int& INTREF; 189typedef INTREF Func1(FLOAT, double); 190typedef float& Func2(int, double); 191 192struct ConvertToFunc { 193 operator Func1*(); // expected-note{{conversion candidate of type 'INTREF (*)(FLOAT, double)'}} 194 operator Func2&(); // expected-note{{conversion candidate of type 'float &(&)(int, double)'}} 195 void operator()(); 196}; 197 198void test_funcptr_call(ConvertToFunc ctf) { 199 int &i1 = ctf(1.0f, 2.0); 200 float &f2 = ctf((short int)1, 1.0f); 201 ctf((long int)17, 2.0); // expected-error{{error: call to object of type 'struct ConvertToFunc' is ambiguous; candidates are:}} 202 ctf(); 203} 204 205struct HasMember { 206 int m; 207}; 208 209struct Arrow1 { 210 HasMember* operator->(); 211}; 212 213struct Arrow2 { 214 Arrow1 operator->(); // expected-note{{candidate function}} 215}; 216 217void test_arrow(Arrow1 a1, Arrow2 a2, const Arrow2 a3) { 218 int &i1 = a1->m; 219 int &i2 = a2->m; 220 a3->m; // expected-error{{no viable overloaded 'operator->'; candidate is}} 221} 222 223struct CopyConBase { 224}; 225 226struct CopyCon : public CopyConBase { 227 CopyCon(const CopyConBase &Base); 228 229 CopyCon(const CopyConBase *Base) { 230 *this = *Base; 231 } 232}; 233 234namespace N { 235 struct X { }; 236} 237 238namespace M { 239 N::X operator+(N::X, N::X); 240} 241 242namespace M { 243 void test_X(N::X x) { 244 (void)(x + x); 245 } 246} 247 248struct AA { bool operator!=(AA&); }; 249struct BB : AA {}; 250bool x(BB y, BB z) { return y != z; } 251 252 253struct AX { 254 AX& operator ->(); // expected-note {{declared at}} 255 int b; 256}; 257 258void m() { 259 AX a; 260 a->b = 0; // expected-error {{circular pointer delegation detected}} 261} 262 263struct CircA { 264 struct CircB& operator->(); // expected-note {{declared at}} 265 int val; 266}; 267struct CircB { 268 struct CircC& operator->(); // expected-note {{declared at}} 269}; 270struct CircC { 271 struct CircA& operator->(); // expected-note {{declared at}} 272}; 273 274void circ() { 275 CircA a; 276 a->val = 0; // expected-error {{circular pointer delegation detected}} 277} 278 279// PR5360: Arrays should lead to built-in candidates for subscript. 280typedef enum { 281 LastReg = 23, 282} Register; 283class RegAlloc { 284 int getPriority(Register r) { 285 return usepri[r]; 286 } 287 int usepri[LastReg + 1]; 288}; 289 290// PR5546: Don't generate incorrect and ambiguous overloads for multi-level 291// arrays. 292namespace pr5546 293{ 294 enum { X }; 295 extern const char *const sMoveCommands[][2][2]; 296 const char* a() { return sMoveCommands[X][0][0]; } 297 const char* b() { return (*(sMoveCommands+X))[0][0]; } 298} 299 300// PR5512 and its discussion 301namespace pr5512 { 302 struct Y { 303 operator short(); 304 operator float(); 305 }; 306 void g_test(Y y) { 307 short s = 0; 308 // DR507, this should be ambiguous, but we special-case assignment 309 s = y; 310 // Note: DR507, this is ambiguous as specified 311 //s += y; 312 } 313 314 struct S {}; 315 void operator +=(int&, S); 316 void f(S s) { 317 int i = 0; 318 i += s; 319 } 320 321 struct A {operator int();}; 322 int a; 323 void b(A x) { 324 a += x; 325 } 326} 327