brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.6 KiB · f3e241c Raw
300 lines · cpp
1// RUN: %clang_cc1 -std=c++2a -verify %s2 3struct B {};4 5template<typename T = void>6  bool operator<(const B&, const B&) = default; // expected-error {{comparison operator template cannot be defaulted}}7 8struct A {9  friend bool operator==(const A&, const A&) = default;10  friend bool operator!=(const A&, const B&) = default; // expected-error {{parameters for defaulted equality comparison operator must have the same type (found 'const A &' vs 'const B &')}}11  friend bool operator!=(const B&, const B&) = default; // expected-error {{invalid parameter type for defaulted equality comparison}}12  friend bool operator<(const A&, const A&);13  friend bool operator<(const B&, const B&) = default; // expected-error {{invalid parameter type for defaulted relational comparison}}14  friend bool operator>(A, A) = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}15 16  bool operator<(const A&) const;17  bool operator<=(const A&) const = default;18  bool operator==(const A&) const && = default; // expected-error {{ref-qualifier '&&' is not allowed on a defaulted comparison operator}}19  bool operator<=(const A&&) const = default; // expected-error {{invalid parameter type for defaulted relational comparison operator; found 'const A &&', expected 'const A &'}}20  bool operator<=(const int&) const = default; // expected-error {{invalid parameter type for defaulted relational comparison operator; found 'const int &', expected 'const A &'}}21  bool operator>=(const A&) const volatile = default; // expected-error {{defaulted comparison function must not be volatile}}22  bool operator<=>(const A&) = default; // expected-error {{defaulted member three-way comparison operator must be const-qualified}}23  bool operator>=(const B&) const = default; // expected-error-re {{invalid parameter type for defaulted relational comparison operator; found 'const B &', expected 'const A &'{{$}}}}24  static bool operator>(const B&) = default; // expected-error {{overloaded 'operator>' cannot be a static member function}}25  friend bool operator>(A, const A&) = default; // expected-error {{must have the same type}} expected-note {{would be the best match}}26 27  template<typename T = void>28    friend bool operator==(const A&, const A&) = default; // expected-error {{comparison operator template cannot be defaulted}}29  template<typename T = void>30    bool operator==(const A&) const = default; // expected-error {{comparison operator template cannot be defaulted}}31};32 33template<class C> struct D {34  C i;35  friend bool operator==(const D&, D) = default; // expected-error {{must have the same type}}36  friend bool operator>(D, const D&) = default; // expected-error {{must have the same type}}37  friend bool operator<(const D&, const D&) = default;38  friend bool operator<=(D, D) = default;39 40  bool operator!=(D) const = default; // expected-error {{invalid parameter type for defaulted equality comparison operator}}41};42 43template<typename T> struct Dependent {44  using U = typename T::type;45  bool operator==(U) const = default; // expected-error {{found 'U'}}46  friend bool operator==(U, U) = default; // expected-error {{found 'U'}}47};48 49struct Good { using type = const Dependent<Good>&; };50template struct Dependent<Good>;51 52struct Bad { using type = Dependent<Bad>&; };53template struct Dependent<Bad>; // expected-note {{in instantiation of}}54 55 56namespace std {57  struct strong_ordering {58    int n;59    constexpr operator int() const { return n; }60    static const strong_ordering equal, greater, less;61  };62  constexpr strong_ordering strong_ordering::equal = {0};63  constexpr strong_ordering strong_ordering::greater = {1};64  constexpr strong_ordering strong_ordering::less = {-1};65}66 67namespace LookupContext {68  struct A {};69 70  namespace N {71    template <typename T> auto f() {72      bool operator==(const T &, const T &);73      bool operator<(const T &, const T &);74      struct B {75        T a;76        std::strong_ordering operator<=>(const B &) const = default;77      };78      return B();79    }80 81    auto g() {82      struct Cmp { Cmp(std::strong_ordering); };83      Cmp operator<=>(const A&, const A&);84      bool operator!=(const Cmp&, int);85      struct B {86        A a;87        Cmp operator<=>(const B &) const = default;88      };89      return B();90    }91 92    auto h() {93      struct B;94      bool operator==(const B&, const B&);95      bool operator!=(const B&, const B&); // expected-note 2{{best match}}96      std::strong_ordering operator<=>(const B&, const B&);97      bool operator<(const B&, const B&); // expected-note 2{{best match}}98      bool operator<=(const B&, const B&); // expected-note 2{{best match}}99      bool operator>(const B&, const B&); // expected-note 2{{best match}}100      bool operator>=(const B&, const B&); // expected-note 2{{best match}}101 102      struct B {103        bool operator!=(const B&) const = default; // expected-warning {{implicitly deleted}} expected-note {{deleted here}} expected-note{{replace 'default'}}104        bool operator<(const B&) const = default; // expected-warning {{implicitly deleted}} expected-note {{deleted here}} expected-note{{replace 'default'}}105        bool operator<=(const B&) const = default; // expected-warning {{implicitly deleted}} expected-note {{deleted here}} expected-note{{replace 'default'}}106        bool operator>(const B&) const = default; // expected-warning {{implicitly deleted}} expected-note {{deleted here}} expected-note{{replace 'default'}}107        bool operator>=(const B&) const = default; // expected-warning {{implicitly deleted}} expected-note {{deleted here}} expected-note{{replace 'default'}}108      };109      return B();110    }111  }112 113  namespace M {114    bool operator==(const A &, const A &) = delete;115    bool operator<(const A &, const A &) = delete;116    bool cmp = N::f<A>() < N::f<A>();117 118    void operator<=>(const A &, const A &) = delete;119    auto cmp2 = N::g() <=> N::g();120 121    void use_h() {122      N::h() != N::h(); // expected-error {{implicitly deleted}}123      N::h() < N::h(); // expected-error {{implicitly deleted}}124      N::h() <= N::h(); // expected-error {{implicitly deleted}}125      N::h() > N::h(); // expected-error {{implicitly deleted}}126      N::h() >= N::h(); // expected-error {{implicitly deleted}}127    }128  }129}130 131namespace evil1 {132template <class T> struct Bad {133  // expected-error@+1{{found 'const float &'}}134  bool operator==(T const &) const = default;135  Bad(int = 0);136};137 138template <class T> struct Weird {139  // expected-error@+1{{'float' cannot be used prior to '::'}}140  bool operator==(typename T::Weird_ const &) const = default;141  Weird(int = 0);142};143 144struct evil {145  using Weird_ = Weird<evil>;146};147template struct Bad<float>;   // expected-note{{evil1::Bad<float>' requested}}148template struct Weird<float>; // expected-note{{evil1::Weird<float>' requested}}149template struct Weird<evil>;150 151} // namespace evil1152 153namespace P1946 {154  struct A {155    friend bool operator==(A &, A &); // expected-note {{would lose const qualifier}}156  };157  struct B {158    A a; // expected-note {{no viable 'operator=='}}159    friend bool operator==(B, B) = default; // ok160    friend bool operator==(const B&, const B&) = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}161  };162}163 164namespace p2085 {165// out-of-class defaulting166 167struct S1 {168  bool operator==(S1 const &) const;169};170 171bool S1::operator==(S1 const &) const = default;172 173bool F1(S1 &s) {174  return s != s;175}176 177struct S2 {178  friend bool operator==(S2 const &, S2 const &);179};180 181bool operator==(S2 const &, S2 const &) = default;182bool F2(S2 &s) {183  return s != s;184}185 186struct S3 {};                                      // expected-note{{here}}187bool operator==(S3 const &, S3 const &) = default; // expected-error{{not a friend}}188 189struct S4;                                         // expected-note{{forward declaration}}190bool operator==(S4 const &, S4 const &) = default; // expected-error{{not a friend}}191 192struct S5;                         // expected-note 3{{forward declaration}}193bool operator==(S5, S5) = default; // expected-error{{not a friend}} expected-error 2{{has incomplete type}}194 195struct S6;196bool operator==(const S6&, const S6&); // expected-note {{previous declaration}}197struct S6 {198    friend bool operator==(const S6&, const S6&) = default; // expected-error {{because it was already declared outside}}199};200 201struct S7 {202  bool operator==(S7 const &) const &&;203};204bool S7::operator==(S7 const &) const && = default; // expected-error {{ref-qualifier '&&' is not allowed on a defaulted comparison operator}}205 206enum e {};207bool operator==(e, int) = default; // expected-error{{expected class or reference to a constant class}}208 209bool operator==(e *, int *) = default; // expected-error{{must have at least one}}210} // namespace p2085211 212namespace p2085_2 {213template <class T> struct S6 {214  bool operator==(T const &) const;215};216// expected-error@+2{{found 'const int &'}}217// expected-error@+1{{found 'const float &'}}218template <class T> bool S6<T>::operator==(T const &) const = default;219 220template struct S6<int>; // expected-note{{S6<int>::operator==' requested}}221 222void f1() {223  S6<float> a;224  (void)(a == 0); // expected-note{{S6<float>::operator==' requested}}225}226 227template <class T> struct S7 {228  // expected-error@+2{{'float' cannot be used}}229  // expected-error@+1{{'int' cannot be used}}230  bool operator==(typename T::S7_ const &) const;231  S7(int = 0);232};233template <class T> bool S7<T>::operator==(typename T::S7_ const &) const = default;234 235struct evil {236  using S7_ = S7<evil>;237};238template struct S7<float>; // expected-note{{S7<float>' requested}}239 240void f2() {241  S7<int> a; // expected-note{{S7<int>' requested}}242  S7<evil> b;243  (void)(a == 0); // expected-error{{invalid operands}}244  (void)(b == 0);245}246} // namespace p2085_2247 248namespace GH61417 {249struct A {250  unsigned x : 1;251  unsigned   : 0;252  unsigned y : 1;253 254  constexpr A() : x(0), y(0) {}255  bool operator==(const A& rhs) const noexcept = default;256};257 258void f1() {259  constexpr A a, b;260  constexpr bool c = (a == b); // no diagnostic, we should not be comparing the261                               // unnamed bit-field which is indeterminate262}263 264void f2() {265    A a, b;266    bool c = (a == b); // no diagnostic nor crash during codegen attempting to267                       // access info for unnamed bit-field268}269}270 271namespace GH96043 {272template <typename> class a {};273template <typename b> b c(a<b>);274template <typename d> class e {275public:276  typedef a<d *> f;277  f begin();278};279template <typename d, typename g> constexpr bool operator==(d h, g i) {280  return *c(h.begin()) == *c(i.begin());281}282struct j {283  e<j> bar;284  bool operator==(const j &) const;285};286bool j::operator==(const j &) const = default;287}288 289namespace evil2 {290  struct k {291  };292  293  struct l {294      friend bool operator==(const l& a, const l& b);295      friend class k;296  };297  298  bool operator==(const l& a, const l& b) = default;299}300