[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / CXX / except / except.spec / p11-2a.cpp
blob5950bce8c2e7d7f600f3c21af4ff426b4b9549b6
1 // RUN: %clang_cc1 -std=c++2a -verify %s
2 // RUN: %clang_cc1 -std=c++2a -verify %s -DDEFINE_FIRST
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 is
7 // potentially-throwing if and only if any expression in the implicit
8 // definition is potentially-throwing.
10 #define CAT2(a, b) a ## b
11 #define CAT(a, b) CAT2(a, b)
13 #ifdef DEFINE_FIRST
14 #define DEF(x) auto CAT(a, __LINE__) = x
15 #else
16 #define DEF(x)
17 #endif
19 namespace std {
20 struct strong_ordering {
21 int n;
22 static const strong_ordering equal, less, greater;
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;
29 namespace Eq {
30 struct A {
31 bool operator==(const A&) const = default;
33 DEF(A() == A());
34 static_assert(noexcept(A() == A()));
36 struct B {
37 bool operator==(const B&) const;
39 struct C {
40 B b;
41 bool operator==(const C&) const = default;
43 DEF(C() == C());
44 static_assert(!noexcept(C() == C()));
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}}
52 struct E {
53 D<E> d;
54 bool operator==(const E&) const = default;
56 static_assert(!noexcept(E() == E()));
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}}
63 bool equal = F() == F();
64 static_assert(!noexcept(F() == F()));
67 namespace Spaceship {
68 struct X {
69 friend std::strong_ordering operator<=>(X, X);
71 struct Y : X {
72 friend std::strong_ordering operator<=>(Y, Y) = default;
74 DEF(Y() <=> Y());
75 static_assert(!noexcept(Y() <=> Y()));
77 struct ThrowingCmpCat {
78 ThrowingCmpCat(std::strong_ordering);
79 operator std::strong_ordering();
81 bool operator!=(ThrowingCmpCat o, int n) noexcept;
83 struct A {
84 friend ThrowingCmpCat operator<=>(A, A) noexcept;
87 struct B {
88 A a;
89 std::strong_ordering operator<=>(const B&) const = default;
91 DEF(B() <=> B());
92 static_assert(!noexcept(B() <=> B()));
94 struct C {
95 int n;
96 ThrowingCmpCat operator<=>(const C&) const = default;
98 DEF(C() <=> C());
99 static_assert(!noexcept(C() <=> C()));
101 struct D {
102 int n;
103 std::strong_ordering operator<=>(const D&) const = default;
105 DEF(D() <=> D());
106 static_assert(noexcept(D() <=> D()));
109 struct ThrowingCmpCat2 {
110 ThrowingCmpCat2(std::strong_ordering) noexcept;
111 operator std::strong_ordering() noexcept;
113 bool operator!=(ThrowingCmpCat2 o, int n);
115 struct E {
116 friend ThrowingCmpCat2 operator<=>(E, E) noexcept;
119 struct F {
120 E e;
121 std::strong_ordering operator<=>(const F&) const = default;
123 DEF(F() <=> F());
124 static_assert(noexcept(F() <=> F()));
126 struct G {
127 int n;
128 ThrowingCmpCat2 operator<=>(const G&) const = default;
130 DEF(G() <=> G());
131 static_assert(!noexcept(G() <=> G()));
134 namespace Synth {
135 struct A {
136 friend bool operator==(A, A) noexcept;
137 friend bool operator<(A, A) noexcept;
139 struct B {
140 A a;
141 friend std::strong_ordering operator<=>(B, B) = default;
143 std::strong_ordering operator<=>(B, B) noexcept;
145 struct C {
146 friend bool operator==(C, C);
147 friend bool operator<(C, C) noexcept;
149 struct D {
150 C c;
151 friend std::strong_ordering operator<=>(D, D) = default; // expected-note {{previous}}
153 std::strong_ordering operator<=>(D, D) noexcept; // expected-error {{does not match}}
155 struct E {
156 friend bool operator==(E, E) noexcept;
157 friend bool operator<(E, E);
159 struct F {
160 E e;
161 friend std::strong_ordering operator<=>(F, F) = default; // expected-note {{previous}}
163 std::strong_ordering operator<=>(F, F) noexcept; // expected-error {{does not match}}
166 namespace Secondary {
167 struct A {
168 friend bool operator==(A, A);
169 friend bool operator!=(A, A) = default; // expected-note {{previous}}
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}}
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}}
183 struct B {
184 friend bool operator==(B, B) noexcept;
185 friend bool operator!=(B, B) = default;
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;
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;
200 // Check that we attempt to define a defaulted comparison before trying to
201 // compute its exception specification.
202 namespace 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}}
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}}
213 template struct A<2>;
214 bool operator!=(const A<2>&, const A<2>&) noexcept; // expected-note {{in evaluation of exception specification}}
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}}
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}}