1// RUN: %clang_cc1 -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}} 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 3{{candidate function}} 37 38void h(A a, const A ac, Z z) { 39 make_A() == z; // expected-warning{{equality comparison result unused}} 40 a == z; // expected-error{{use of overloaded operator '==' is ambiguous}} 41 ac == z; // expected-error{{invalid operands to binary expression ('const A' and 'Z')}} 42} 43 44struct B { 45 bool operator==(const B&) const; 46 47 void test(Z z) { 48 make_A() == z; // expected-warning{{equality comparison result unused}} 49 } 50}; 51 52// we shouldn't see warnings about self-comparison, 53// this is a member function, we dunno what it'll do 54bool i(B b) 55{ 56 return b == b; 57} 58 59enum Enum1 { }; 60enum Enum2 { }; 61 62struct E1 { 63 E1(Enum1) { } 64}; 65 66struct E2 { 67 E2(Enum2); 68}; 69 70// C++ [over.match.oper]p3 - enum restriction. 71float& operator==(E1, E2); // expected-note{{candidate function}} 72 73void enum_test(Enum1 enum1, Enum2 enum2, E1 e1, E2 e2, Enum1 next_enum1) { 74 float &f1 = (e1 == e2); 75 float &f2 = (enum1 == e2); 76 float &f3 = (e1 == enum2); 77 float &f4 = (enum1 == next_enum1); // expected-error{{non-const lvalue reference to type 'float' cannot bind to a temporary of type 'bool'}} 78} 79 80// PR5244 - Argument-dependent lookup would include the two operators below, 81// which would break later assumptions and lead to a crash. 82class pr5244_foo 83{ 84 pr5244_foo(int); 85 pr5244_foo(char); 86}; 87 88bool operator==(const pr5244_foo& s1, const pr5244_foo& s2); // expected-note{{candidate function}} 89bool operator==(char c, const pr5244_foo& s); // expected-note{{candidate function}} 90 91enum pr5244_bar 92{ 93 pr5244_BAR 94}; 95 96class pr5244_baz 97{ 98public: 99 pr5244_bar quux; 100}; 101 102void pr5244_barbaz() 103{ 104 pr5244_baz quuux; 105 (void)(pr5244_BAR == quuux.quux); 106} 107 108 109 110struct PostInc { 111 PostInc operator++(int); 112 PostInc& operator++(); 113}; 114 115struct PostDec { 116 PostDec operator--(int); 117 PostDec& operator--(); 118}; 119 120void incdec_test(PostInc pi, PostDec pd) { 121 const PostInc& pi1 = pi++; 122 const PostDec& pd1 = pd--; 123 PostInc &pi2 = ++pi; 124 PostDec &pd2 = --pd; 125} 126 127struct SmartPtr { 128 int& operator*(); 129 long& operator*() const volatile; 130}; 131 132void test_smartptr(SmartPtr ptr, const SmartPtr cptr, 133 const volatile SmartPtr cvptr) { 134 int &ir = *ptr; 135 long &lr = *cptr; 136 long &lr2 = *cvptr; 137} 138 139 140struct ArrayLike { 141 int& operator[](int); 142}; 143 144void test_arraylike(ArrayLike a) { 145 int& ir = a[17]; 146} 147 148struct SmartRef { 149 int* operator&(); 150}; 151 152void test_smartref(SmartRef r) { 153 int* ip = &r; 154} 155 156bool& operator,(X, Y); 157 158void test_comma(X x, Y y) { 159 bool& b1 = (x, y); 160 X& xr = (x, x); // expected-warning {{expression result unused}} 161} 162 163struct Callable { 164 int& operator()(int, double = 2.71828); // expected-note{{candidate function}} 165 float& operator()(int, double, long, ...); // expected-note{{candidate function}} 166 167 double& operator()(float); // expected-note{{candidate function}} 168}; 169 170struct Callable2 { 171 int& operator()(int i = 0); 172 double& operator()(...) const; 173}; 174 175struct DerivesCallable : public Callable { 176}; 177 178void test_callable(Callable c, Callable2 c2, const Callable2& c2c, 179 DerivesCallable dc) { 180 int &ir = c(1); 181 float &fr = c(1, 3.14159, 17, 42); 182 183 c(); // expected-error{{no matching function for call to object of type 'Callable'}} 184 185 double &dr = c(1.0f); 186 187 int &ir2 = c2(); 188 int &ir3 = c2(1); 189 double &fr2 = c2c(); 190 191 int &ir4 = dc(17); 192 double &fr3 = dc(3.14159f); 193} 194 195typedef float FLOAT; 196typedef int& INTREF; 197typedef INTREF Func1(FLOAT, double); 198typedef float& Func2(int, double); 199 200struct ConvertToFunc { 201 operator Func1*(); // expected-note 2{{conversion candidate of type 'INTREF (*)(FLOAT, double)'}} 202 operator Func2&(); // expected-note 2{{conversion candidate of type 'float &(&)(int, double)'}} 203 void operator()(); 204}; 205 206struct ConvertToFuncDerived : ConvertToFunc { }; 207 208void test_funcptr_call(ConvertToFunc ctf, ConvertToFuncDerived ctfd) { 209 int &i1 = ctf(1.0f, 2.0); 210 float &f1 = ctf((short int)1, 1.0f); 211 ctf((long int)17, 2.0); // expected-error{{call to object of type 'ConvertToFunc' is ambiguous}} 212 ctf(); 213 214 int &i2 = ctfd(1.0f, 2.0); 215 float &f2 = ctfd((short int)1, 1.0f); 216 ctfd((long int)17, 2.0); // expected-error{{call to object of type 'ConvertToFuncDerived' is ambiguous}} 217 ctfd(); 218} 219 220struct HasMember { 221 int m; 222}; 223 224struct Arrow1 { 225 HasMember* operator->(); 226}; 227 228struct Arrow2 { 229 Arrow1 operator->(); // expected-note{{candidate function}} 230}; 231 232void test_arrow(Arrow1 a1, Arrow2 a2, const Arrow2 a3) { 233 int &i1 = a1->m; 234 int &i2 = a2->m; 235 a3->m; // expected-error{{no viable overloaded 'operator->'}} 236} 237 238struct CopyConBase { 239}; 240 241struct CopyCon : public CopyConBase { 242 CopyCon(const CopyConBase &Base); 243 244 CopyCon(const CopyConBase *Base) { 245 *this = *Base; 246 } 247}; 248 249namespace N { 250 struct X { }; 251} 252 253namespace M { 254 N::X operator+(N::X, N::X); 255} 256 257namespace M { 258 void test_X(N::X x) { 259 (void)(x + x); 260 } 261} 262 263struct AA { bool operator!=(AA&); }; 264struct BB : AA {}; 265bool x(BB y, BB z) { return y != z; } 266 267 268struct AX { 269 AX& operator ->(); // expected-note {{declared here}} 270 int b; 271}; 272 273void m() { 274 AX a; 275 a->b = 0; // expected-error {{circular pointer delegation detected}} 276} 277 278struct CircA { 279 struct CircB& operator->(); // expected-note {{declared here}} 280 int val; 281}; 282struct CircB { 283 struct CircC& operator->(); // expected-note {{declared here}} 284}; 285struct CircC { 286 struct CircA& operator->(); // expected-note {{declared here}} 287}; 288 289void circ() { 290 CircA a; 291 a->val = 0; // expected-error {{circular pointer delegation detected}} 292} 293 294// PR5360: Arrays should lead to built-in candidates for subscript. 295typedef enum { 296 LastReg = 23, 297} Register; 298class RegAlloc { 299 int getPriority(Register r) { 300 return usepri[r]; 301 } 302 int usepri[LastReg + 1]; 303}; 304 305// PR5546: Don't generate incorrect and ambiguous overloads for multi-level 306// arrays. 307namespace pr5546 308{ 309 enum { X }; 310 extern const char *const sMoveCommands[][2][2]; 311 const char* a() { return sMoveCommands[X][0][0]; } 312 const char* b() { return (*(sMoveCommands+X))[0][0]; } 313} 314 315// PR5512 and its discussion 316namespace pr5512 { 317 struct Y { 318 operator short(); 319 operator float(); 320 }; 321 void g_test(Y y) { 322 short s = 0; 323 // DR507, this should be ambiguous, but we special-case assignment 324 s = y; 325 // Note: DR507, this is ambiguous as specified 326 //s += y; 327 } 328 329 struct S {}; 330 void operator +=(int&, S); 331 void f(S s) { 332 int i = 0; 333 i += s; 334 } 335 336 struct A {operator int();}; 337 int a; 338 void b(A x) { 339 a += x; 340 } 341} 342 343// PR5900 344namespace pr5900 { 345 struct NotAnArray {}; 346 void test0() { 347 NotAnArray x; 348 x[0] = 0; // expected-error {{does not provide a subscript operator}} 349 } 350 351 struct NonConstArray { 352 int operator[](unsigned); // expected-note {{candidate}} 353 }; 354 int test1() { 355 const NonConstArray x = NonConstArray(); 356 return x[0]; // expected-error {{no viable overloaded operator[] for type}} 357 } 358 359 // Not really part of this PR, but implemented at the same time. 360 struct NotAFunction {}; 361 void test2() { 362 NotAFunction x; 363 x(); // expected-error {{does not provide a call operator}} 364 } 365} 366 367// Operator lookup through using declarations. 368namespace N { 369 struct X2 { }; 370} 371 372namespace N2 { 373 namespace M { 374 namespace Inner { 375 template<typename T> 376 N::X2 &operator<<(N::X2&, const T&); 377 } 378 using Inner::operator<<; 379 } 380} 381 382void test_lookup_through_using() { 383 using namespace N2::M; 384 N::X2 x; 385 x << 17; 386} 387 388namespace rdar9136502 { 389 struct X { 390 int i(); 391 int i(int); 392 }; 393 394 struct Y { 395 Y &operator<<(int); 396 }; 397 398 void f(X x, Y y) { 399 y << x.i; // expected-error{{reference to non-static member function must be called}} 400 } 401} 402 403namespace rdar9222009 { 404class StringRef { 405 inline bool operator==(StringRef LHS, StringRef RHS) { // expected-error{{overloaded 'operator==' must be a binary operator (has 3 parameters)}} 406 return !(LHS == RHS); // expected-error{{invalid operands to binary expression ('rdar9222009::StringRef' and 'rdar9222009::StringRef')}} 407 } 408}; 409 410} 411 412namespace PR11784 { 413 struct A { A& operator=(void (*x)()); }; 414 void f(); 415 void f(int); 416 void g() { A x; x = f; } 417} 418 419namespace test10 { 420 struct A { 421 void operator[](float (*fn)(int)); // expected-note 2 {{not viable: no overload of 'bar' matching 'float (*)(int)'}} 422 }; 423 424 float foo(int); 425 float foo(float); 426 427 template <class T> T bar(T); 428 template <class T, class U> T bar(U); 429 430 void test(A &a) { 431 a[&foo]; 432 a[foo]; 433 434 a[&bar<int>]; // expected-error {{no viable overloaded operator[]}} 435 a[bar<int>]; // expected-error {{no viable overloaded operator[]}} 436 437 // If these fail, it's because we're not letting the overload 438 // resolution for operator| resolve the overload of 'bar'. 439 a[&bar<float>]; 440 a[bar<float>]; 441 } 442} 443