706 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify=expected,precxx23 -std=c++11 %s2// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx23 -std=c++23 %s3 4class X { };5 6X operator+(X, X);7 8void f(X x) {9 x = x + x;10}11 12struct Y;13struct Z;14 15struct Y {16 Y(const Z&);17};18 19struct Z {20 Z(const Y&);21};22 23Y operator+(Y, Y);24bool operator-(Y, Y); // expected-note{{candidate function}}25bool operator-(Z, Z); // expected-note{{candidate function}}26 27void g(Y y, Z z) {28 y = y + z;29 bool b = y - z; // expected-error{{use of overloaded operator '-' is ambiguous}}30}31 32struct A {33 bool operator==(Z&); // expected-note 2{{candidate function}}34};35 36A make_A();37 38bool operator==(A&, Z&); // expected-note 3{{candidate function}} \39 // cxx23-note 2{{candidate function}}40 41 42void 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 48struct 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 do58bool i(B b)59{60 return b == b;61}62 63enum Enum1 { };64enum Enum2 { };65 66struct E1 {67 E1(Enum1) { }68};69 70struct E2 {71 E2(Enum2);72};73 74// C++ [over.match.oper]p3 - enum restriction.75float& operator==(E1, E2); // expected-note{{candidate function}} \76 // cxx23-note{{candidate function}}77 78 79void 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.88class pr5244_foo89{90 pr5244_foo(int);91 pr5244_foo(char);92};93 94bool operator==(const pr5244_foo& s1, const pr5244_foo& s2); // expected-note{{candidate function}}95bool operator==(char c, const pr5244_foo& s); // expected-note{{candidate function}} \96 // cxx23-note{{candidate function}}97 98enum pr5244_bar99{100 pr5244_BAR101};102 103class pr5244_baz104{105public:106 pr5244_bar quux;107};108 109void pr5244_barbaz()110{111 pr5244_baz quuux;112 (void)(pr5244_BAR == quuux.quux);113}114 115 116 117struct PostInc {118 PostInc operator++(int);119 PostInc& operator++();120};121 122struct PostDec {123 PostDec operator--(int);124 PostDec& operator--();125};126 127void 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 134struct SmartPtr {135 int& operator*();136 long& operator*() const volatile;137};138 139void 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 147struct ArrayLike {148 int& operator[](int);149};150 151void test_arraylike(ArrayLike a) {152 int& ir = a[17];153}154 155struct SmartRef {156 int* operator&();157};158 159void test_smartref(SmartRef r) {160 int* ip = &r;161}162 163bool& operator,(X, Y);164 165void 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 170struct 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 177struct Callable2 {178 int& operator()(int i = 0);179 double& operator()(...) const;180};181 182struct DerivesCallable : public Callable {183};184 185void 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 202typedef float FLOAT;203typedef int& INTREF;204typedef INTREF Func1(FLOAT, double);205typedef float& Func2(int, double);206 207struct 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 213struct ConvertToFuncDerived : ConvertToFunc { };214 215void 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 227struct HasMember {228 int m;229};230 231struct Arrow1 {232 HasMember* operator->();233};234 235struct Arrow2 {236 Arrow1 operator->(); // expected-note{{candidate function}}237};238 239void 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 245struct CopyConBase {246};247 248struct CopyCon : public CopyConBase {249 CopyCon(const CopyConBase &Base);250 251 CopyCon(const CopyConBase *Base) {252 *this = *Base;253 }254};255 256namespace N {257 struct X { };258}259 260namespace M {261 N::X operator+(N::X, N::X);262}263 264namespace M {265 void test_X(N::X x) {266 (void)(x + x);267 }268}269 270struct AA { bool operator!=(AA&); };271struct BB : AA {};272bool x(BB y, BB z) { return y != z; }273 274 275struct AX { 276 AX& operator ->(); // expected-note {{declared here}}277 int b;278}; 279 280void m() {281 AX a; 282 a->b = 0; // expected-error {{circular pointer delegation detected}}283}284 285struct CircA {286 struct CircB& operator->(); // expected-note {{declared here}}287 int val;288};289struct CircB {290 struct CircC& operator->(); // expected-note {{declared here}}291};292struct CircC {293 struct CircA& operator->(); // expected-note {{declared here}}294};295 296void 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.302typedef enum {303 LastReg = 23,304} Register;305class 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-level313// arrays.314namespace pr5546315{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 discussion323namespace 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 assignment331 s = y;332 // Note: DR507, this is ambiguous as specified333 //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// PR5900351namespace 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.375namespace N {376 struct X2 { };377}378 379namespace 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 389void test_lookup_through_using() {390 using namespace N2::M;391 N::X2 x;392 x << 17;393}394 395namespace 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 << x407 .i; // expected-error{{reference to non-static member function must be called; did you mean to call it with no arguments?}}408 }409}410 411namespace rdar9222009 {412class 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 420namespace PR11784 {421 struct A { A& operator=(void (*x)()); };422 void f();423 void f(int);424 void g() { A x; x = f; }425}426 427namespace 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 overload446 // resolution for operator| resolve the overload of 'bar'.447 a[&bar<float>];448 a[bar<float>];449 }450}451 452struct InvalidOperatorEquals {453 InvalidOperatorEquals operator=() = delete; // expected-error {{overloaded 'operator=' must be a binary operator}}454};455 456namespace 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 463namespace PR14995 {464 struct B {};465 template<typename ...T> void operator++(B, T...) {}466 467 void f() {468 B b;469 b++; // ok470 ++b; // ok471 }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--; // ok482 --prefix; // ok483 }484 485 struct D {};486 template<typename T> void operator++(D, T) {}487 488 void h() {489 D d;490 d++; // ok491 ++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 PR14995516 517namespace 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 530namespace 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 543namespace 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; // OK555 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 561namespace 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 596namespace test {597namespace A {598template<typename T> T f(T t) {599 T operator+(T, T);600 return t + t;601}602}603namespace B {604 struct X {};605}606void g(B::X x) { A::f(x); }607}608 609namespace GH78314 {610 611class a {612public: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 619class 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 628void 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 638class 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 >= 202002L650namespace 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#endif685 686#if __cplusplus >= 201703L687namespace GH88329 {688 689template <auto T> struct A {};690template <auto T> A<*T> operator *() { return {}; }691// expected-error@-1 {{overloaded 'operator*' must have at least one parameter of class or enumeration type}}692}693 694namespace GH92275 {695 696template <auto v>697struct constant{};698 699template <auto x>700auto operator *(constant<x>)701{ return constant<(*x)>{}; }702 703}704 705#endif706