1 // RUN: %clang_cc1 -std=c++2a -verify %s
4 struct B
{ bool operator==(B
) const; };
5 struct C
{ int operator==(C
) const; };
7 // expected-note@+2 {{candidate function not viable: 'this' argument has type 'const}}
8 // expected-note@+1 {{candidate function (with reversed parameter order) not viable: 1st argument ('const}}
12 E(const E
&) = delete; // expected-note {{deleted}}
13 int operator==(E
) const; // expected-note {{passing}}
15 struct F
{ void operator==(F
) const; };
16 struct G
{ bool operator==(G
) const = delete; }; // expected-note {{deleted here}}
19 bool operator==(const H1
&) const = default;
20 bool operator<(const H1
&) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
21 // expected-note@-1 {{because there is no viable three-way comparison function for 'H1'}}
25 bool operator==(const H2
&) const = default;
26 bool operator<(const H2
&) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
27 // expected-note@-1 {{because there is no viable three-way comparison function for 'H2'}}
31 bool operator==(const H3
&) const = default;
32 bool operator<(const H3
&) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}
33 // expected-note@-1 {{because there is no viable three-way comparison function for 'H3'}}
37 template<typename T
> struct X
{
39 bool operator==(const X
&) const = default; // #x expected-note 4{{deleted here}}
40 T t
; // expected-note 3{{because there is no viable 'operator==' for member 't'}}
41 // expected-note@-1 {{because it would invoke a deleted comparison function for member 't'}}
45 bool operator==(const Mutable
&) const = default;
50 void(X
<A
>() == X
<A
>()); // expected-error {{cannot be compared because its 'operator==' is implicitly deleted}}
51 void(X
<B
>() == X
<B
>());
52 void(X
<C
>() == X
<C
>());
53 void(X
<D
>() == X
<D
>()); // expected-error {{cannot be compared because its 'operator==' is implicitly deleted}}
54 void(Mutable() == Mutable());
56 // FIXME: We would benefit from a note identifying the member of 'X' we were comparing here and below.
57 // expected-error@#x {{call to deleted constructor of 'E'}}
58 void(X
<E
>() == X
<E
>()); // expected-note {{in defaulted equality comparison operator for 'X<E>' first required here}}
60 // FIXME: We would benefit from a note pointing at the selected 'operator==' here.
61 // expected-error@#x {{value of type 'void' is not contextually convertible to 'bool'}}
62 void(X
<F
>() == X
<F
>()); // expected-note {{in defaulted equality comparison operator for 'X<F>' first required here}}
64 void(X
<G
>() == X
<G
>()); // expected-error {{cannot be compared because its 'operator==' is implicitly deleted}}
66 void(X
<A
[3]>() == X
<A
[3]>()); // expected-error {{cannot be compared because its 'operator==' is implicitly deleted}}
67 void(X
<B
[3]>() == X
<B
[3]>());
72 bool operator==(const A
&) const; // expected-note 2{{implicitly declared private here}}
74 struct B
: A
{ // expected-note 2{{because it would invoke a private 'operator==' to compare base class 'A'}}
75 bool operator==(const B
&) const = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}
76 friend bool operator==(const B
&, const B
&) = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}
81 bool operator==(const C
&) const; // expected-note 2{{declared protected here}}
84 bool operator==(const D
&) const = default;
85 friend bool operator==(const D
&, const D
&) = default;
88 C c
; // expected-note 2{{because it would invoke a protected 'operator==' member of 'Access::C' to compare member 'c'}}
89 bool operator==(const E
&) const = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}
90 friend bool operator==(const E
&, const E
&) = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}
97 bool operator==(const G
&) const = default;
98 friend bool operator==(const G
&, const G
&) = default;
103 using C::operator==; // expected-note 2{{declared private here}}
105 struct I
: H
{ // expected-note 2{{private 'operator==' to compare base class 'H'}}
106 bool operator==(const I
&) const = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}
107 friend bool operator==(const I
&, const I
&) = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}
111 bool operator==(const J
&) const;
116 bool operator==(const K
&) const = default;
117 friend bool operator==(const K
&, const K
&) = default;
121 bool operator==(const X
&) const; // expected-note {{ambiguity is between a regular call to this operator and a call with the argument order reversed}}
123 struct Y
: private X
{ // expected-note {{private}}
127 // Note: this function is not deleted. The selected operator== is
128 // accessible. But the derived-to-base conversion involves an inaccessible
129 // base class, which we don't check for until we define the function.
130 bool operator==(const Z
&) const = default; // expected-error {{cannot cast 'const Y' to its private base class 'const X'}} expected-warning {{ambiguous}}
132 bool z
= Z() == Z(); // expected-note {{first required here}}