brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.5 KiB · 5648cea Raw
216 lines · cpp
1// RUN: %clang_cc1 -std=c++2a -verify %s2 3namespace std {4  class strong_ordering {5    int n;6    constexpr strong_ordering(int n) : n(n) {}7  public:8    static const strong_ordering less, equal, greater;9    bool operator!=(int) { return n != 0; }10  };11  constexpr strong_ordering strong_ordering::less{-1},12      strong_ordering::equal{0}, strong_ordering::greater{1};13 14  class weak_ordering {15    int n;16    constexpr weak_ordering(int n) : n(n) {}17  public:18    constexpr weak_ordering(strong_ordering o);19    static const weak_ordering less, equivalent, greater;20    bool operator!=(int) { return n != 0; }21  };22  constexpr weak_ordering weak_ordering::less{-1},23      weak_ordering::equivalent{0}, weak_ordering::greater{1};24 25  class partial_ordering {26    int n;27    constexpr partial_ordering(int n) : n(n) {}28  public:29    constexpr partial_ordering(strong_ordering o);30    constexpr partial_ordering(weak_ordering o);31    static const partial_ordering less, equivalent, greater, unordered;32    bool operator!=(int) { return n != 0; }33  };34  constexpr partial_ordering partial_ordering::less{-1},35      partial_ordering::equivalent{0}, partial_ordering::greater{1},36      partial_ordering::unordered{2};37}38 39namespace DeducedNotCat {40  struct A {41    A operator<=>(const A&) const; // expected-note {{selected 'operator<=>' for member 'a' declared here}}42  };43  struct B {44    A a; // expected-note {{return type 'A' of three-way comparison for member 'a' is not a standard comparison category type}}45    auto operator<=>(const B&) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}46  };47}48 49namespace DeducedVsSynthesized {50  struct A {51    bool operator==(const A&) const;52    bool operator<(const A&) const;53  };54  struct B {55    A a; // expected-note {{no viable three-way comparison function for member 'a'}}56    auto operator<=>(const B&) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}57  };58}59 60namespace Deduction {61  template<typename T> struct wrap {62    T t;63    friend auto operator<=>(const wrap&, const wrap&) = default;64  };65 66  using strong = wrap<int>;67  using strong2 = wrap<int*>;68  struct weak {69    friend std::weak_ordering operator<=>(weak, weak);70  };71  using partial = wrap<float>;72 73  template<typename ...T> struct A : T... {74    friend auto operator<=>(const A&, const A&) = default;75  };76 77  template<typename Expected, typename ...Ts> void f() {78    using T = Expected; // expected-note {{previous}}79    using T = decltype(A<Ts...>() <=> A<Ts...>()); // expected-error {{different type}}80    void(A<Ts...>() <=> A<Ts...>()); // trigger synthesis of body81  }82 83  template void f<std::strong_ordering>();84  template void f<std::strong_ordering, strong>();85  template void f<std::strong_ordering, strong, strong2>();86 87  template void f<std::weak_ordering, weak>();88  template void f<std::weak_ordering, weak, strong>();89  template void f<std::weak_ordering, strong, weak>();90 91  template void f<std::partial_ordering, partial>();92  template void f<std::partial_ordering, weak, partial>();93  template void f<std::partial_ordering, strong, partial>();94  template void f<std::partial_ordering, partial, weak>();95  template void f<std::partial_ordering, partial, strong>();96  template void f<std::partial_ordering, weak, partial, strong>();97 98  // Check that the above mechanism works.99  template void f<std::strong_ordering, weak>(); // expected-note {{instantiation of}}100 101  std::strong_ordering x = A<strong>() <=> A<strong>();102}103 104namespace PR44723 {105  // Make sure we trigger return type deduction for a callee 'operator<=>'106  // before inspecting its return type.107  template<int> struct a {108    friend constexpr auto operator<=>(a const &lhs, a const &rhs) {109      return std::strong_ordering::equal;110    }111  };112  struct b {113    friend constexpr auto operator<=>(b const &, b const &) = default;114    a<0> m_value;115  };116  std::strong_ordering cmp_b = b() <=> b();117 118  struct c {119    auto operator<=>(const c&) const&; // expected-note {{selected 'operator<=>' for base class 'c' declared here}}120  };121  struct d : c { // expected-note {{base class 'c' declared here}}122    friend auto operator<=>(const d&, const d&) = default; // #d123    // expected-error@#d {{return type of defaulted 'operator<=>' cannot be deduced because three-way comparison for base class 'c' has a deduced return type and is not yet defined}}124    // expected-warning@#d {{implicitly deleted}}125    // expected-note@#d {{replace 'default'}}126  };127  auto c::operator<=>(const c&) const& { // #c128    return std::strong_ordering::equal;129  }130  // expected-error@+1 {{overload resolution selected deleted operator '<=>'}}131  std::strong_ordering cmp_d = d() <=> d();132  // expected-note@#c 2{{candidate}}133  // expected-note@#d {{candidate function has been implicitly deleted}}134}135 136namespace BadDeducedType {137  struct A {138    // expected-error@+1 {{deduced return type for defaulted three-way comparison operator must be 'auto', not 'auto &'}}139    friend auto &operator<=>(const A&, const A&) = default;140  };141 142  struct B {143    // expected-error@+1 {{deduced return type for defaulted three-way comparison operator must be 'auto', not 'const auto'}}144    friend const auto operator<=>(const B&, const B&) = default;145  };146 147  template<typename T> struct X {}; // expected-note {{here}}148  struct C {149    // expected-error@+1 {{deduction not allowed in function return type}}150    friend X operator<=>(const C&, const C&) = default;151  };152 153  template<typename T> concept CmpCat = true;154  struct D {155    // expected-error@+1 {{deduced return type for defaulted three-way comparison operator must be 'auto', not 'CmpCat auto'}}156    friend CmpCat auto operator<=>(const D&, const D&) = default;157  };158}159 160namespace PR48856 {161  struct A {162    auto operator<=>(const A &) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}163    void (*x)();                                 // expected-note {{because there is no viable three-way comparison function for member 'x'}}164  };165 166  struct B {167    auto operator<=>(const B &) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}168    void (B::*x)();                              // expected-note {{because there is no viable three-way comparison function for member 'x'}}169  };170 171  struct C {172    auto operator<=>(const C &) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}173    int C::*x;                                   // expected-note {{because there is no viable three-way comparison function for member 'x'}}174  };175}176 177namespace PR50591 {178  struct a1 {179    operator int() const;180  };181  struct b1 {182    auto operator<=>(b1 const &) const = default;183    a1 f;184  };185  std::strong_ordering cmp_b1 = b1() <=> b1();186 187  struct a2 {188    operator float() const;189  };190  struct b2 {191    auto operator<=>(b2 const &) const = default;192    a2 f;193  };194  std::partial_ordering cmp_b2 = b2() <=> b2();195 196  using fp = void (*)();197 198  struct a3 {199    operator fp() const;200  };201  struct b3 {202    auto operator<=>(b3 const &) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}203    a3 f;                                         // expected-note {{because there is no viable three-way comparison function}}204  };205 206  struct a4 { // Test that function pointer conversion operator here is ignored for this overload resolution.207    operator int() const;208    operator fp() const;209  };210  struct b4 {211    auto operator<=>(b4 const &) const = default;212    a4 f;213  };214  std::strong_ordering cmp_b4 = b4() <=> b4();215}216