Skip to content

Commit

Permalink
[clang] Improve diagnostics on implicitly deleted defaulted comparisons
Browse files Browse the repository at this point in the history
This patch just makes the error message clearer by reinforcing the cause
was a lack of viable **three-way** comparison function for the
**complete object**.

Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>

Reviewed By: rsmith

Differential Revision: https://reviews.llvm.org/D97990
  • Loading branch information
mizvekov committed Mar 13, 2021
1 parent bbd0dc3 commit c9fd92d
Show file tree
Hide file tree
Showing 8 changed files with 18 additions and 18 deletions.
4 changes: 2 additions & 2 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -8979,8 +8979,8 @@ def note_defaulted_comparison_calls_deleted : Note<
"defaulted %0 is implicitly deleted because it would invoke a deleted "
"comparison function%select{| for member %2| for base class %2}1">;
def note_defaulted_comparison_no_viable_function : Note<
"defaulted %0 is implicitly deleted because there is no viable comparison "
"function%select{| for member %2| for base class %2}1">;
"defaulted %0 is implicitly deleted because there is no viable three-way "
"comparison function for%select{| member| base class}1 %2">;
def note_defaulted_comparison_no_viable_function_synthesized : Note<
"three-way comparison cannot be synthesized because there is no viable "
"function for %select{'=='|'<'}0 comparison">;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7632,7 +7632,7 @@ class DefaultedComparisonAnalyzer

private:
Subobject getCompleteObject() {
return Subobject{Subobject::CompleteObject, nullptr, FD->getLocation()};
return Subobject{Subobject::CompleteObject, RD, FD->getLocation()};
}

Subobject getBase(CXXBaseSpecifier *Base) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ namespace P1946 {
friend bool operator==(A &, A &); // expected-note {{would lose const qualifier}}
};
struct B {
A a; // expected-note {{no viable comparison}}
A a; // expected-note {{no viable three-way comparison}}
friend bool operator==(B, B) = default; // ok
friend bool operator==(const B&, const B&) = default; // expected-warning {{deleted}}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ struct A3 {

bool operator==(const A3 &) const = default; // expected-warning {{implicitly deleted}}
bool operator<(const A3 &) const = default; // expected-warning {{implicitly deleted}}
// expected-note@-1 {{because there is no viable comparison function}}
// expected-note@-1 {{because there is no viable three-way comparison function for 'A3'}}
};

struct B1 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ namespace DeleteAfterFirstDecl {
struct Q {
struct X {
friend std::strong_ordering operator<=>(const X&, const X&);
} x; // expected-note {{no viable comparison}}
} x; // expected-note {{no viable three-way comparison}}
// expected-error@+1 {{defaulting the corresponding implicit 'operator==' for this defaulted 'operator<=>' would delete it after its first declaration}}
friend std::strong_ordering operator<=>(const Q&, const Q&) = default;
};
Expand Down
8 changes: 4 additions & 4 deletions clang/test/CXX/class/class.compare/class.eq/p2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,26 @@ struct G { bool operator==(G) const = delete; }; // expected-note {{deleted here
struct H1 {
bool operator==(const H1 &) const = default;
bool operator<(const H1 &) const = default; // expected-warning {{implicitly deleted}}
// expected-note@-1 {{because there is no viable comparison function}}
// expected-note@-1 {{because there is no viable three-way comparison function for 'H1'}}
void (*x)();
};
struct H2 {
bool operator==(const H2 &) const = default;
bool operator<(const H2 &) const = default; // expected-warning {{implicitly deleted}}
// expected-note@-1 {{because there is no viable comparison function}}
// expected-note@-1 {{because there is no viable three-way comparison function for 'H2'}}
void (H2::*x)();
};
struct H3 {
bool operator==(const H3 &) const = default;
bool operator<(const H3 &) const = default; // expected-warning {{implicitly deleted}}
// expected-note@-1 {{because there is no viable comparison function}}
// expected-note@-1 {{because there is no viable three-way comparison function for 'H3'}}
int H3::*x;
};

template<typename T> struct X {
X();
bool operator==(const X&) const = default; // #x expected-note 4{{deleted here}}
T t; // expected-note 3{{because there is no viable comparison function for member 't'}}
T t; // expected-note 3{{because there is no viable three-way comparison function for member 't'}}
// expected-note@-1 {{because it would invoke a deleted comparison function for member 't'}}
};

Expand Down
8 changes: 4 additions & 4 deletions clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ namespace Deletedness {
};

// expected-note@#base {{deleted comparison function for base class 'C'}}
// expected-note@#base {{no viable comparison function for base class 'D1'}}
// expected-note@#base {{no viable three-way comparison function for base class 'D1'}}
// expected-note@#base {{three-way comparison cannot be synthesized because there is no viable function for '<' comparison}}
// expected-note@#base {{no viable comparison function for base class 'D2'}}
// expected-note@#base {{no viable three-way comparison function for base class 'D2'}}
// expected-note@#base {{three-way comparison cannot be synthesized because there is no viable function for '==' comparison}}
// expected-note@#base {{deleted comparison function for base class 'E'}}
// expected-note@#base {{implied comparison for base class 'F' is ambiguous}}
Expand Down Expand Up @@ -110,9 +110,9 @@ namespace Deletedness {
}

// expected-note@#arr {{deleted comparison function for member 'arr'}}
// expected-note@#arr {{no viable comparison function for member 'arr'}}
// expected-note@#arr {{no viable three-way comparison function for member 'arr'}}
// expected-note@#arr {{three-way comparison cannot be synthesized because there is no viable function for '<' comparison}}
// expected-note@#arr {{no viable comparison function for member 'arr'}}
// expected-note@#arr {{no viable three-way comparison function for member 'arr'}}
// expected-note@#arr {{three-way comparison cannot be synthesized because there is no viable function for '==' comparison}}
// expected-note@#arr {{deleted comparison function for member 'arr'}}
// expected-note@#arr {{implied comparison for member 'arr' is ambiguous}}
Expand Down
8 changes: 4 additions & 4 deletions clang/test/CXX/class/class.compare/class.spaceship/p2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ namespace DeducedVsSynthesized {
bool operator<(const A&) const;
};
struct B {
A a; // expected-note {{no viable comparison function for member 'a'}}
A a; // expected-note {{no viable three-way comparison function for member 'a'}}
auto operator<=>(const B&) const = default; // expected-warning {{implicitly deleted}}
};
}
Expand Down Expand Up @@ -159,16 +159,16 @@ namespace BadDeducedType {
namespace PR48856 {
struct A {
auto operator<=>(const A &) const = default; // expected-warning {{implicitly deleted}}
void (*x)(); // expected-note {{because there is no viable comparison function for member 'x'}}
void (*x)(); // expected-note {{because there is no viable three-way comparison function for member 'x'}}
};

struct B {
auto operator<=>(const B &) const = default; // expected-warning {{implicitly deleted}}
void (B::*x)(); // expected-note {{because there is no viable comparison function for member 'x'}}
void (B::*x)(); // expected-note {{because there is no viable three-way comparison function for member 'x'}}
};

struct C {
auto operator<=>(const C &) const = default; // expected-warning {{implicitly deleted}}
int C::*x; // expected-note {{because there is no viable comparison function for member 'x'}}
int C::*x; // expected-note {{because there is no viable three-way comparison function for member 'x'}}
};
}

0 comments on commit c9fd92d

Please sign in to comment.