brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.0 KiB · 7e801f4 Raw
232 lines · cpp
1// RUN: %clang_cc1 -std=c++2a -verify %s -fcxx-exceptions2 3namespace std {4  struct strong_ordering { // expected-note 6{{candidate}}5    int n;6    constexpr operator int() const { return n; }7    static const strong_ordering less, equal, greater;8  };9  constexpr strong_ordering strong_ordering::less{-1},10      strong_ordering::equal{0}, strong_ordering::greater{1};11 12  struct weak_ordering {13    int n;14    constexpr weak_ordering(int n) : n(n) {}15    constexpr weak_ordering(strong_ordering o) : n(o.n) {}16    constexpr operator int() const { return n; }17    static const weak_ordering less, equivalent, greater;18  };19  constexpr weak_ordering weak_ordering::less{-1},20      weak_ordering::equivalent{0}, weak_ordering::greater{1};21 22  struct partial_ordering {23    double d;24    constexpr partial_ordering(double d) : d(d) {}25    constexpr partial_ordering(strong_ordering o) : d(o.n) {}26    constexpr partial_ordering(weak_ordering o) : d(o.n) {}27    constexpr operator double() const { return d; }28    static const partial_ordering less, equivalent, greater, unordered;29  };30  constexpr partial_ordering partial_ordering::less{-1},31      partial_ordering::equivalent{0}, partial_ordering::greater{1},32      partial_ordering::unordered{__builtin_nan("")};33 34  static_assert(!(partial_ordering::unordered < 0));35  static_assert(!(partial_ordering::unordered == 0));36  static_assert(!(partial_ordering::unordered > 0));37}38 39namespace Deletedness {40  struct A {41    std::strong_ordering operator<=>(const A&) const;42  };43  struct B {44    bool operator==(const B&) const;45    bool operator<(const B&) const;46  };47  struct C {48    std::strong_ordering operator<=>(const C&) const = delete; // expected-note 2{{deleted}}49  };50  struct D1 {51    bool operator==(const D1&) const;52    std::strong_ordering operator<=>(int) const; // expected-note 2{{function not viable}} expected-note 2{{function (with reversed parameter order) not viable}}53    bool operator<(int) const; // expected-note 2{{function not viable}}54  };55  struct D2 {56    bool operator<(const D2&) const;57    std::strong_ordering operator<=>(int) const; // expected-note 2{{function not viable}} expected-note 2{{function (with reversed parameter order) not viable}}58    bool operator==(int) const; // expected-note 2{{function not viable}}59  };60  struct E {61    bool operator==(const E&) const;62    bool operator<(const E&) const = delete; // expected-note 2{{deleted}}63  };64  struct F {65    std::strong_ordering operator<=>(const F&) const; // expected-note 2{{candidate}}66    std::strong_ordering operator<=>(F) const; // expected-note 2{{candidate}}67  };68  struct G1 {69    bool operator==(const G1&) const;70    void operator<(const G1&) const;71  };72  struct G2 {73    void operator==(const G2&) const;74    bool operator<(const G2&) const;75  };76  struct H {77    void operator<=>(const H&) const;78  };79 80  // expected-note@#base {{deleted comparison function for base class 'C'}}81  // expected-note@#base {{no viable three-way comparison function for base class 'D1'}}82  // expected-note@#base {{three-way comparison cannot be synthesized because there is no viable function for '<' comparison}}83  // expected-note@#base {{no viable 'operator==' for base class 'D2'}}84  // expected-note@#base {{three-way comparison cannot be synthesized because there is no viable function for '==' comparison}}85  // expected-note@#base {{deleted comparison function for base class 'E'}}86  // expected-note@#base {{implied comparison for base class 'F' is ambiguous}}87  template<typename T> struct Cmp : T { // #base88    std::strong_ordering operator<=>(const Cmp&) const = default; // #cmp expected-note 5{{here}}89  };90 91  void use(...);92  void f() {93    use(94      Cmp<A>() <=> Cmp<A>(),95      Cmp<B>() <=> Cmp<B>(),96      Cmp<C>() <=> Cmp<C>(), // expected-error {{deleted}}97      Cmp<D1>() <=> Cmp<D1>(), // expected-error {{deleted}}98      Cmp<D2>() <=> Cmp<D2>(), // expected-error {{deleted}}99      Cmp<E>() <=> Cmp<E>(), // expected-error {{deleted}}100      Cmp<F>() <=> Cmp<F>(), // expected-error {{deleted}}101      // FIXME: The following three errors are not very good.102      // expected-error@#cmp {{value of type 'void' is not contextually convertible to 'bool'}}103      Cmp<G1>() <=> Cmp<G1>(), // expected-note-re {{in defaulted three-way comparison operator for '{{.*}}Cmp<{{.*}}G1>' first required here}}j104      // expected-error@#cmp {{value of type 'void' is not contextually convertible to 'bool'}}105      Cmp<G2>() <=> Cmp<G2>(), // expected-note-re {{in defaulted three-way comparison operator for '{{.*}}Cmp<{{.*}}G2>' first required here}}j106      // expected-error@#cmp {{no matching conversion for static_cast from 'void' to 'std::strong_ordering'}}107      Cmp<H>() <=> Cmp<H>(), // expected-note-re {{in defaulted three-way comparison operator for '{{.*}}Cmp<{{.*}}H>' first required here}}j108      0109    );110  }111 112  // expected-note@#arr {{deleted comparison function for member 'arr'}}113  // expected-note@#arr {{no viable three-way comparison function for member 'arr'}}114  // expected-note@#arr {{three-way comparison cannot be synthesized because there is no viable function for '<' comparison}}115  // expected-note@#arr {{no viable 'operator==' for member 'arr'}}116  // expected-note@#arr {{three-way comparison cannot be synthesized because there is no viable function for '==' comparison}}117  // expected-note@#arr {{deleted comparison function for member 'arr'}}118  // expected-note@#arr {{implied comparison for member 'arr' is ambiguous}}119  template<typename T> struct CmpArray {120    T arr[3]; // #arr121    std::strong_ordering operator<=>(const CmpArray&) const = default; // #cmparray expected-note 5{{here}}122  };123  void g() {124    use(125      CmpArray<A>() <=> CmpArray<A>(),126      CmpArray<B>() <=> CmpArray<B>(),127      CmpArray<C>() <=> CmpArray<C>(), // expected-error {{deleted}}128      CmpArray<D1>() <=> CmpArray<D1>(), // expected-error {{deleted}}129      CmpArray<D2>() <=> CmpArray<D2>(), // expected-error {{deleted}}130      CmpArray<E>() <=> CmpArray<E>(), // expected-error {{deleted}}131      CmpArray<F>() <=> CmpArray<F>(), // expected-error {{deleted}}132      // FIXME: The following three errors are not very good.133      // expected-error@#cmparray {{value of type 'void' is not contextually convertible to 'bool'}}134      CmpArray<G1>() <=> CmpArray<G1>(), // expected-note-re {{in defaulted three-way comparison operator for '{{.*}}CmpArray<{{.*}}G1>' first required here}}j135      // expected-error@#cmparray {{value of type 'void' is not contextually convertible to 'bool'}}136      CmpArray<G2>() <=> CmpArray<G2>(), // expected-note-re {{in defaulted three-way comparison operator for '{{.*}}CmpArray<{{.*}}G2>' first required here}}j137      // expected-error@#cmparray {{no matching conversion for static_cast from 'void' to 'std::strong_ordering'}}138      CmpArray<H>() <=> CmpArray<H>(), // expected-note-re {{in defaulted three-way comparison operator for '{{.*}}CmpArray<{{.*}}H>' first required here}}j139      0140    );141  }142}143 144namespace Access {145  class A {146    std::strong_ordering operator<=>(const A &) const; // expected-note {{here}}147  public:148    bool operator==(const A &) const;149    bool operator<(const A &) const;150  };151  struct B {152    A a; // expected-note {{would invoke a private 'operator<=>'}}153    friend std::strong_ordering operator<=>(const B &, const B &) = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}154  };155 156  class C {157    std::strong_ordering operator<=>(const C &); // not viable (not const)158    bool operator==(const C &) const; // expected-note {{here}}159    bool operator<(const C &) const;160  };161  struct D {162    C c; // expected-note {{would invoke a private 'operator=='}}163    friend std::strong_ordering operator<=>(const D &, const D &) = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}164  };165}166 167namespace Synthesis {168  enum Result { False, True, Mu };169 170  constexpr bool toBool(Result R) {171    if (R == Mu) throw "should not ask this question";172    return R == True;173  }174 175  struct Val {176    Result equal, less;177    constexpr bool operator==(const Val&) const { return toBool(equal); }178    constexpr bool operator<(const Val&) const { return toBool(less); }179  };180 181  template<typename T> struct Cmp {182    Val val;183    friend T operator<=>(const Cmp&, const Cmp&) = default; // expected-note {{deleted}}184  };185 186  template<typename T> constexpr auto cmp(Result equal, Result less = Mu, Result reverse_less = Mu) {187    return Cmp<T>{equal, less} <=> Cmp<T>{Mu, reverse_less};188  }189 190  static_assert(cmp<std::strong_ordering>(True) == 0);191  static_assert(cmp<std::strong_ordering>(False, True) < 0);192  static_assert(cmp<std::strong_ordering>(False, False) > 0);193 194  static_assert(cmp<std::weak_ordering>(True) == 0);195  static_assert(cmp<std::weak_ordering>(False, True) < 0);196  static_assert(cmp<std::weak_ordering>(False, False) > 0);197 198  static_assert(cmp<std::partial_ordering>(True) == 0);199  static_assert(cmp<std::partial_ordering>(False, True) < 0);200  static_assert(cmp<std::partial_ordering>(False, False, True) > 0);201  static_assert(!(cmp<std::partial_ordering>(False, False, False) > 0));202  static_assert(!(cmp<std::partial_ordering>(False, False, False) == 0));203  static_assert(!(cmp<std::partial_ordering>(False, False, False) < 0));204 205  // No synthesis is performed for a custom return type, even if it can be206  // converted from a standard ordering.207  struct custom_ordering {208    custom_ordering(std::strong_ordering o);209  };210  void f(Cmp<custom_ordering> c) {211    c <=> c; // expected-error {{deleted}}212  }213}214 215namespace Preference {216  struct A {217    A(const A&) = delete; // expected-note {{deleted}}218    // "usable" candidate that can't actually be called219    friend void operator<=>(A, A); // expected-note {{passing}}220    // Callable candidates for synthesis not considered.221    friend bool operator==(A, A);222    friend bool operator<(A, A);223  };224 225  struct B {226    B();227    A a;228    std::strong_ordering operator<=>(const B&) const = default; // expected-error {{call to deleted constructor of 'A'}}229  };230  bool x = B() < B(); // expected-note {{in defaulted three-way comparison operator for 'B' first required here}}231}232