brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.6 KiB · 5950bce Raw
227 lines · cpp
1// RUN: %clang_cc1 -std=c++2a -verify %s2// RUN: %clang_cc1 -std=c++2a -verify %s -DDEFINE_FIRST3 4// As modified by P2002R0:5//   The exception specification for a comparison operator function (12.6.2)6//   without a noexcept-specifier that is defaulted on its first declaration is7//   potentially-throwing if and only if any expression in the implicit8//   definition is potentially-throwing.9 10#define CAT2(a, b) a ## b11#define CAT(a, b) CAT2(a, b)12 13#ifdef DEFINE_FIRST14#define DEF(x) auto CAT(a, __LINE__) = x15#else16#define DEF(x)17#endif18 19namespace std {20  struct strong_ordering {21    int n;22    static const strong_ordering equal, less, greater;23  };24  constexpr strong_ordering strong_ordering::equal{0},25      strong_ordering::less{-1}, strong_ordering::greater{1};26  bool operator!=(std::strong_ordering o, int n) noexcept;27}28 29namespace Eq {30  struct A {31    bool operator==(const A&) const = default;32  };33  DEF(A() == A());34  static_assert(noexcept(A() == A()));35 36  struct B {37    bool operator==(const B&) const;38  };39  struct C {40    B b;41    bool operator==(const C&) const = default;42  };43  DEF(C() == C());44  static_assert(!noexcept(C() == C()));45 46  // Ensure we do not trigger odr-use from exception specification computation.47  template<typename T> struct D {48    bool operator==(const D &) const {49      typename T::error error; // expected-error {{no type}}50    }51  };52  struct E {53    D<E> d;54    bool operator==(const E&) const = default;55  };56  static_assert(!noexcept(E() == E()));57 58  // (but we do when defining the function).59  struct F {60    D<F> d;61    bool operator==(const F&) const = default; // expected-note {{in instantiation}}62  };63  bool equal = F() == F();64  static_assert(!noexcept(F() == F()));65}66 67namespace Spaceship {68  struct X {69    friend std::strong_ordering operator<=>(X, X);70  };71  struct Y : X {72    friend std::strong_ordering operator<=>(Y, Y) = default;73  };74  DEF(Y() <=> Y());75  static_assert(!noexcept(Y() <=> Y()));76 77  struct ThrowingCmpCat {78    ThrowingCmpCat(std::strong_ordering);79    operator std::strong_ordering();80  };81  bool operator!=(ThrowingCmpCat o, int n) noexcept;82 83  struct A {84    friend ThrowingCmpCat operator<=>(A, A) noexcept;85  };86 87  struct B {88    A a;89    std::strong_ordering operator<=>(const B&) const = default;90  };91  DEF(B() <=> B());92  static_assert(!noexcept(B() <=> B()));93 94  struct C {95    int n;96    ThrowingCmpCat operator<=>(const C&) const = default;97  };98  DEF(C() <=> C());99  static_assert(!noexcept(C() <=> C()));100 101  struct D {102    int n;103    std::strong_ordering operator<=>(const D&) const = default;104  };105  DEF(D() <=> D());106  static_assert(noexcept(D() <=> D()));107 108 109  struct ThrowingCmpCat2 {110    ThrowingCmpCat2(std::strong_ordering) noexcept;111    operator std::strong_ordering() noexcept;112  };113  bool operator!=(ThrowingCmpCat2 o, int n);114 115  struct E {116    friend ThrowingCmpCat2 operator<=>(E, E) noexcept;117  };118 119  struct F {120    E e;121    std::strong_ordering operator<=>(const F&) const = default;122  };123  DEF(F() <=> F());124  static_assert(noexcept(F() <=> F()));125 126  struct G {127    int n;128    ThrowingCmpCat2 operator<=>(const G&) const = default;129  };130  DEF(G() <=> G());131  static_assert(!noexcept(G() <=> G()));132}133 134namespace Synth {135  struct A {136    friend bool operator==(A, A) noexcept;137    friend bool operator<(A, A) noexcept;138  };139  struct B {140    A a;141    friend std::strong_ordering operator<=>(B, B) = default;142  };143  std::strong_ordering operator<=>(B, B) noexcept;144 145  struct C {146    friend bool operator==(C, C);147    friend bool operator<(C, C) noexcept;148  };149  struct D {150    C c;151    friend std::strong_ordering operator<=>(D, D) = default; // expected-note {{previous}}152  };153  std::strong_ordering operator<=>(D, D) noexcept; // expected-error {{does not match}}154 155  struct E {156    friend bool operator==(E, E) noexcept;157    friend bool operator<(E, E);158  };159  struct F {160    E e;161    friend std::strong_ordering operator<=>(F, F) = default; // expected-note {{previous}}162  };163  std::strong_ordering operator<=>(F, F) noexcept; // expected-error {{does not match}}164}165 166namespace Secondary {167  struct A {168    friend bool operator==(A, A);169    friend bool operator!=(A, A) = default; // expected-note {{previous}}170 171    friend int operator<=>(A, A);172    friend bool operator<(A, A) = default; // expected-note {{previous}}173    friend bool operator<=(A, A) = default; // expected-note {{previous}}174    friend bool operator>(A, A) = default; // expected-note {{previous}}175    friend bool operator>=(A, A) = default; // expected-note {{previous}}176  };177  bool operator!=(A, A) noexcept; // expected-error {{does not match}}178  bool operator<(A, A) noexcept; // expected-error {{does not match}}179  bool operator<=(A, A) noexcept; // expected-error {{does not match}}180  bool operator>(A, A) noexcept; // expected-error {{does not match}}181  bool operator>=(A, A) noexcept; // expected-error {{does not match}}182 183  struct B {184    friend bool operator==(B, B) noexcept;185    friend bool operator!=(B, B) = default;186 187    friend int operator<=>(B, B) noexcept;188    friend bool operator<(B, B) = default;189    friend bool operator<=(B, B) = default;190    friend bool operator>(B, B) = default;191    friend bool operator>=(B, B) = default;192  };193  bool operator!=(B, B) noexcept;194  bool operator<(B, B) noexcept;195  bool operator<=(B, B) noexcept;196  bool operator>(B, B) noexcept;197  bool operator>=(B, B) noexcept;198}199 200// Check that we attempt to define a defaulted comparison before trying to201// compute its exception specification.202namespace DefineBeforeComputingExceptionSpec {203  template<int> struct A {204    A();205    A(const A&) = delete; // expected-note 3{{here}}206    friend bool operator==(A, A); // expected-note 3{{passing}}207    friend bool operator!=(const A&, const A&) = default; // expected-error 3{{call to deleted constructor}}208  };209 210  bool a0 = A<0>() != A<0>(); // expected-note {{in defaulted equality comparison operator}}211  bool a1 = operator!=(A<1>(), A<1>()); // expected-note {{in defaulted equality comparison operator}}212 213  template struct A<2>;214  bool operator!=(const A<2>&, const A<2>&) noexcept; // expected-note {{in evaluation of exception specification}}215 216  template<int> struct B {217    B();218    B(const B&) = delete; // expected-note 3{{here}}219    friend bool operator==(B, B); // expected-note 3{{passing}}220    bool operator!=(const B&) const = default; // expected-error 3{{call to deleted constructor}}221  };222 223  bool b0 = B<0>() != B<0>(); // expected-note {{in defaulted equality comparison operator}}224  bool b1 = B<1>().operator!=(B<1>()); // expected-note {{in defaulted equality comparison operator}}225  int b2 = sizeof(&B<2>::operator!=); // expected-note {{in evaluation of exception specification}}226}227