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