1 // RUN: %clang_cc1 -std=c++2a -verify %s
5 template<typename T
= void>
6 bool operator<(const B
&, const B
&) = default; // expected-error {{comparison operator template cannot be defaulted}}
9 friend bool operator==(const A
&, const A
&) = default;
10 friend bool operator!=(const A
&, const B
&) = default; // expected-error {{parameters for defaulted equality comparison operator must have the same type (found 'const A &' vs 'const B &')}}
11 friend bool operator!=(const B
&, const B
&) = default; // expected-error {{invalid parameter type for defaulted equality comparison}}
12 friend bool operator<(const A
&, const A
&);
13 friend bool operator<(const B
&, const B
&) = default; // expected-error {{invalid parameter type for defaulted relational comparison}}
14 friend bool operator>(A
, A
) = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
16 bool operator<(const A
&) const;
17 bool operator<=(const A
&) const = default;
18 bool operator==(const A
&) const && = default; // expected-error {{ref-qualifier '&&' is not allowed on a defaulted comparison operator}}
19 bool operator>=(const A
&) const volatile = default; // expected-error {{defaulted comparison function must not be volatile}}
20 bool operator<=>(const A
&) = default; // expected-error {{defaulted member three-way comparison operator must be const-qualified}}
21 bool operator>=(const B
&) const = default; // expected-error-re {{invalid parameter type for defaulted relational comparison operator; found 'const B &', expected 'const A &'{{$}}}}
22 static bool operator>(const B
&) = default; // expected-error {{overloaded 'operator>' cannot be a static member function}}
23 friend bool operator>(A
, const A
&) = default; // expected-error {{must have the same type}} expected-note {{would be the best match}}
25 template<typename T
= void>
26 friend bool operator==(const A
&, const A
&) = default; // expected-error {{comparison operator template cannot be defaulted}}
27 template<typename T
= void>
28 bool operator==(const A
&) const = default; // expected-error {{comparison operator template cannot be defaulted}}
31 template<class C
> struct D
{
33 friend bool operator==(const D
&, D
) = default; // expected-error {{must have the same type}}
34 friend bool operator>(D
, const D
&) = default; // expected-error {{must have the same type}}
35 friend bool operator<(const D
&, const D
&) = default;
36 friend bool operator<=(D
, D
) = default;
38 bool operator!=(D
) const = default; // expected-error {{invalid parameter type for defaulted equality comparison operator}}
41 template<typename T
> struct Dependent
{
42 using U
= typename
T::type
;
43 bool operator==(U
) const = default; // expected-error {{found 'U'}}
44 friend bool operator==(U
, U
) = default; // expected-error {{found 'U'}}
47 struct Good
{ using type
= const Dependent
<Good
>&; };
48 template struct Dependent
<Good
>;
50 struct Bad
{ using type
= Dependent
<Bad
>&; };
51 template struct Dependent
<Bad
>; // expected-note {{in instantiation of}}
55 struct strong_ordering
{
57 constexpr operator int() const { return n
; }
58 static const strong_ordering equal
, greater
, less
;
60 constexpr strong_ordering
strong_ordering::equal
= {0};
61 constexpr strong_ordering
strong_ordering::greater
= {1};
62 constexpr strong_ordering
strong_ordering::less
= {-1};
65 namespace LookupContext
{
69 template <typename T
> auto f() {
70 bool operator==(const T
&, const T
&);
71 bool operator<(const T
&, const T
&);
74 std::strong_ordering
operator<=>(const B
&) const = default;
80 struct Cmp
{ Cmp(std::strong_ordering
); };
81 Cmp
operator<=>(const A
&, const A
&);
82 bool operator!=(const Cmp
&, int);
85 Cmp
operator<=>(const B
&) const = default;
92 bool operator==(const B
&, const B
&);
93 bool operator!=(const B
&, const B
&); // expected-note 2{{best match}}
94 std::strong_ordering
operator<=>(const B
&, const B
&);
95 bool operator<(const B
&, const B
&); // expected-note 2{{best match}}
96 bool operator<=(const B
&, const B
&); // expected-note 2{{best match}}
97 bool operator>(const B
&, const B
&); // expected-note 2{{best match}}
98 bool operator>=(const B
&, const B
&); // expected-note 2{{best match}}
101 bool operator!=(const B
&) const = default; // expected-warning {{implicitly deleted}} expected-note {{deleted here}} expected-note{{replace 'default'}}
102 bool operator<(const B
&) const = default; // expected-warning {{implicitly deleted}} expected-note {{deleted here}} expected-note{{replace 'default'}}
103 bool operator<=(const B
&) const = default; // expected-warning {{implicitly deleted}} expected-note {{deleted here}} expected-note{{replace 'default'}}
104 bool operator>(const B
&) const = default; // expected-warning {{implicitly deleted}} expected-note {{deleted here}} expected-note{{replace 'default'}}
105 bool operator>=(const B
&) const = default; // expected-warning {{implicitly deleted}} expected-note {{deleted here}} expected-note{{replace 'default'}}
112 bool operator==(const A
&, const A
&) = delete;
113 bool operator<(const A
&, const A
&) = delete;
114 bool cmp
= N::f
<A
>() < N::f
<A
>();
116 void operator<=>(const A
&, const A
&) = delete;
117 auto cmp2
= N::g() <=> N::g();
120 N::h() != N::h(); // expected-error {{implicitly deleted}}
121 N::h() < N::h(); // expected-error {{implicitly deleted}}
122 N::h() <= N::h(); // expected-error {{implicitly deleted}}
123 N::h() > N::h(); // expected-error {{implicitly deleted}}
124 N::h() >= N::h(); // expected-error {{implicitly deleted}}
130 template <class T
> struct Bad
{
131 // expected-error@+1{{found 'const float &'}}
132 bool operator==(T
const &) const = default;
136 template <class T
> struct Weird
{
137 // expected-error@+1{{'float' cannot be used prior to '::'}}
138 bool operator==(typename
T::Weird_
const &) const = default;
143 using Weird_
= Weird
<evil
>;
145 template struct Bad
<float>; // expected-note{{evil1::Bad<float>' requested}}
146 template struct Weird
<float>; // expected-note{{evil1::Weird<float>' requested}}
147 template struct Weird
<evil
>;
153 friend bool operator==(A
&, A
&); // expected-note {{would lose const qualifier}}
156 A a
; // expected-note {{no viable 'operator=='}}
157 friend bool operator==(B
, B
) = default; // ok
158 friend bool operator==(const B
&, const B
&) = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}
163 // out-of-class defaulting
166 bool operator==(S1
const &) const;
169 bool S1::operator==(S1
const &) const = default;
176 friend bool operator==(S2
const &, S2
const &);
179 bool operator==(S2
const &, S2
const &) = default;
184 struct S3
{}; // expected-note{{here}}
185 bool operator==(S3
const &, S3
const &) = default; // expected-error{{not a friend}}
187 struct S4
; // expected-note{{forward declaration}}
188 bool operator==(S4
const &, S4
const &) = default; // expected-error{{not a friend}}
190 struct S5
; // expected-note 3{{forward declaration}}
191 bool operator==(S5
, S5
) = default; // expected-error{{not a friend}} expected-error 2{{has incomplete type}}
194 bool operator==(const S6
&, const S6
&); // expected-note {{previous declaration}}
196 friend bool operator==(const S6
&, const S6
&) = default; // expected-error {{because it was already declared outside}}
200 bool operator==(S7
const &) const &&;
202 bool S7::operator==(S7
const &) const && = default; // expected-error {{ref-qualifier '&&' is not allowed on a defaulted comparison operator}}
205 bool operator==(e
, int) = default; // expected-error{{expected class or reference to a constant class}}
207 bool operator==(e
*, int *) = default; // expected-error{{must have at least one}}
211 template <class T
> struct S6
{
212 bool operator==(T
const &) const;
214 // expected-error@+2{{found 'const int &'}}
215 // expected-error@+1{{found 'const float &'}}
216 template <class T
> bool S6
<T
>::operator==(T
const &) const = default;
218 template struct S6
<int>; // expected-note{{S6<int>::operator==' requested}}
222 (void)(a
== 0); // expected-note{{S6<float>::operator==' requested}}
225 template <class T
> struct S7
{
226 // expected-error@+2{{'float' cannot be used}}
227 // expected-error@+1{{'int' cannot be used}}
228 bool operator==(typename
T::S7_
const &) const;
231 template <class T
> bool S7
<T
>::operator==(typename
T::S7_
const &) const = default;
234 using S7_
= S7
<evil
>;
236 template struct S7
<float>; // expected-note{{S7<float>' requested}}
239 S7
<int> a
; // expected-note{{S7<int>' requested}}
241 (void)(a
== 0); // expected-error{{invalid operands}}
244 } // namespace p2085_2
252 constexpr A() : x(0), y(0) {}
253 bool operator==(const A
& rhs
) const noexcept
= default;
258 constexpr bool c
= (a
== b
); // no diagnostic, we should not be comparing the
259 // unnamed bit-field which is indeterminate
264 bool c
= (a
== b
); // no diagnostic nor crash during codegen attempting to
265 // access info for unnamed bit-field