brintos

brintos / llvm-project-archived public Read only

0
0
Text · 17.2 KiB · 0701a96 Raw
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