brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.7 KiB · 53a8bfc Raw
183 lines · cpp
1// RUN: %clang_cc1 -std=c++2a -verify=expected,cxx2a %s2// RUN: %clang_cc1 -std=c++23 -verify=expected %s3 4// This test is for [class.compare.default]p3 as modified and renumbered to p45// by P2002R0.6// Also covers modifications made by P2448R27 8namespace std {9  struct strong_ordering {10    int n;11    constexpr operator int() const { return n; }12    static const strong_ordering less, equal, greater;13  };14  constexpr strong_ordering strong_ordering::less = {-1};15  constexpr strong_ordering strong_ordering::equal = {0};16  constexpr strong_ordering strong_ordering::greater = {1};17}18 19namespace N {20  struct A {21    friend constexpr std::strong_ordering operator<=>(const A&, const A&) = default; // expected-note 2{{declared here}}22  };23 24  constexpr std::strong_ordering (*test_a_threeway_not_found)(const A&, const A&) = &operator<=>; // expected-error {{undeclared}}25 26  constexpr std::strong_ordering operator<=>(const A&, const A&) noexcept;27  constexpr std::strong_ordering (*test_a_threeway)(const A&, const A&) = &operator<=>;28  static_assert(!(*test_a_threeway)(A(), A())); // expected-error {{static assertion expression is not an integral constant expression}}29                                               // expected-note@-1 {{undefined function 'operator<=>' cannot be used in a constant expression}}30 31  constexpr bool (*test_a_equal_not_found)(const A&, const A&) = &operator==; // expected-error {{undeclared}}32 33  constexpr bool operator==(const A&, const A&) noexcept;34  constexpr bool (*test_a_equal)(const A&, const A&) noexcept = &operator==;35  static_assert((*test_a_equal)(A(), A())); // expected-error {{static assertion expression is not an integral constant expression}}36                                            // expected-note@-1 {{undefined function 'operator==' cannot be used in a constant expression}}37}38 39struct B1 {40  virtual std::strong_ordering operator<=>(const B1&) const = default;41};42bool (B1::*test_b)(const B1&) const = &B1::operator==;43 44struct C1 : B1 {45  // OK, B1::operator== is virtual.46  bool operator==(const B1&) const override;47};48 49struct B2 {50  std::strong_ordering operator<=>(const B2&) const = default;51};52 53struct C2 : B2 {54  bool operator==(const B2&) const override; // expected-error {{only virtual member functions}}55};56 57struct D {58  std::strong_ordering operator<=>(const D&) const;59  virtual std::strong_ordering operator<=>(const struct E&) const = 0;60};61struct E : D {62  // expected-error@+2 {{only virtual member functions}}63  // expected-note@+1 {{while declaring the corresponding implicit 'operator==' for this defaulted 'operator<=>'}}64  std::strong_ordering operator<=>(const E&) const override = default;65};66 67struct F {68  [[deprecated("oh no")]] std::strong_ordering operator<=>(const F&) const = default; // expected-note 4{{deprecated}}69};70void use_f(F f) {71  void(f <=> f); // expected-warning {{oh no}}72  void(f < f); // expected-warning {{oh no}}73  void(f == f); // expected-warning {{oh no}}74  void(f != f); // expected-warning {{oh no}}75}76 77class G {78  // expected-note@+2 {{implicitly declared private here}}79  // expected-note-re@+1 {{{{^}}declared private here}}80  std::strong_ordering operator<=>(const G&) const = default;81public:82};83void use_g(G g) {84  void(g <=> g); // expected-error {{private}}85  void(g == g); // expected-error {{private}}86}87 88struct H {89  bool operator==(const H&) const; // cxx2a-note {{non-constexpr comparison function declared here}}90  constexpr std::strong_ordering operator<=>(const H&) const { return std::strong_ordering::equal; }91};92 93struct I {94  H h; // cxx2a-note {{non-constexpr comparison function would be used to compare member 'h'}}95  constexpr std::strong_ordering operator<=>(const I&) const = default; // cxx2a-error {{cannot be declared constexpr}}96};97 98struct J {99  std::strong_ordering operator<=>(const J&) const & = default; // expected-note {{candidate function (the implicit 'operator==' for this 'operator<=>)'}}100  friend std::strong_ordering operator<=>(const J&, const J&) = default; // expected-note {{candidate function (the implicit 'operator==' for this 'operator<=>)'}}101};102void use_j(J j) {103  void(j == j); // expected-error {{ambiguous}}104}105 106namespace DeleteAfterFirstDecl {107  bool operator==(const struct Q&, const struct Q&);108  struct Q {109    struct X {110      friend std::strong_ordering operator<=>(const X&, const X&);111    } x; // expected-note {{no viable 'operator=='}}112    // expected-error@+1 {{defaulting the corresponding implicit 'operator==' for this defaulted 'operator<=>' would delete it after its first declaration}}113    friend std::strong_ordering operator<=>(const Q&, const Q&) = default;114  };115}116 117// Note, substitution here results in the second parameter of 'operator=='118// referring to the first parameter of 'operator==', not to the first parameter119// of 'operator<=>'.120// FIXME: Find a case where this matters (attribute enable_if?).121struct K {122  friend std::strong_ordering operator<=>(const K &k, decltype(k)) = default;123};124bool test_k = K() == K();125 126namespace NoInjectionIfOperatorEqualsDeclared {127  struct A {128    void operator==(int); // expected-note 2{{not viable}}129    std::strong_ordering operator<=>(const A&) const = default;130  };131  bool test_a = A() == A(); // expected-error {{invalid operands}}132 133  struct B {134    friend void operator==(int, struct Q); // expected-note 2{{not viable}}135    std::strong_ordering operator<=>(const B&) const = default;136  };137  bool test_b = B() == B(); // expected-error {{invalid operands}}138 139  struct C {140    void operator==(int); // expected-note 2{{not viable}}141    friend std::strong_ordering operator<=>(const C&, const C&) = default;142  };143  bool test_c = C() == C(); // expected-error {{invalid operands}}144 145  struct D {146    void f() {147      void operator==(const D&, int);148    }149    struct X {150      friend void operator==(const D&, int);151    };152    friend std::strong_ordering operator<=>(const D&, const D&) = default;153  };154  bool test_d = D() == D();155}156 157namespace GH61238 {158template <typename A> struct my_struct {159    A value; // cxx2a-note {{non-constexpr comparison function would be used to compare member 'value'}}160 161    constexpr friend bool operator==(const my_struct &, const my_struct &) noexcept = default; // cxx2a-error {{cannot be declared constexpr}}162};163 164struct non_constexpr_type {165    friend bool operator==(non_constexpr_type, non_constexpr_type) noexcept { // cxx2a-note {{non-constexpr comparison function declared here}}166        return false;167    }168};169 170my_struct<non_constexpr_type> obj; // cxx2a-note {{in instantiation of template class 'GH61238::my_struct<GH61238::non_constexpr_type>' requested here}}171}172 173namespace Constrained {174  template<typename T>175  struct A {176    std::strong_ordering operator<=>(const A&) const requires true = default;177  };178 179  bool f(A<int> a) {180    return a != A<int>();181  }182}183