Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / CXX / class / class.compare / class.eq / p2.cpp
blob7ff827e208aa7b09723fda19d85bf755ca570006
1 // RUN: %clang_cc1 -std=c++2a -verify %s
3 struct A {};
4 struct B { bool operator==(B) const; };
5 struct C { int operator==(C) const; };
6 struct D {
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}}
9 bool operator==(D);
11 struct E {
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}}
18 struct H1 {
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'}}
22 void (*x)();
24 struct H2 {
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'}}
28 void (H2::*x)();
30 struct H3 {
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'}}
34 int H3::*x;
37 template<typename T> struct X {
38 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'}}
44 struct Mutable {
45 bool operator==(const Mutable&) const = default;
46 mutable D d;
49 void test() {
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]>());
70 namespace Access {
71 class A {
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'}}
79 class C {
80 protected:
81 bool operator==(const C &) const; // expected-note 2{{declared protected here}}
83 struct D : C {
84 bool operator==(const D &) const = default;
85 friend bool operator==(const D &, const D&) = default;
87 struct E {
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'}}
93 struct F : C {
94 using C::operator==;
96 struct G : F {
97 bool operator==(const G&) const = default;
98 friend bool operator==(const G&, const G&) = default;
101 struct H : C {
102 private:
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'}}
110 class J {
111 bool operator==(const J&) const;
112 friend class K;
114 class K {
115 J j;
116 bool operator==(const K&) const = default;
117 friend bool operator==(const K&, const K&) = default;
120 struct X {
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}}
124 using X::operator==;
126 struct Z : Y {
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}}