Skip to content

Commit

Permalink
[clang] Fix diagnostics for defaulted, implicitly deleted 'operator=='.
Browse files Browse the repository at this point in the history
https://godbolt.org/z/cMKE3o1aG

According to the issue #63960 , compiler falsely complains that no viable `operator<=>` was found while we are actually looking for a `operator==`.
This bug has been fixed through adding a check of the `OverloadedOperatorKind` type's object, `OO`, to see if it is `OO_EqualEqual` in addition to `OO_ExclaimEqual`.

Reviewed By: #clang-language-wg, cor3ntin

Differential Revision: https://reviews.llvm.org/D155714
  • Loading branch information
AMP999 authored and cor3ntin committed Jul 23, 2023
1 parent 142bfaf commit 02bb2be
Show file tree
Hide file tree
Showing 7 changed files with 19 additions and 8 deletions.
6 changes: 4 additions & 2 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -407,8 +407,10 @@ Improvements to Clang's diagnostics
by making use of the syntactical structure of function calls. This avoids display
of syntactically invalid codes in diagnostics.
(`#57081: <https://github.com/llvm/llvm-project/issues/57081>`_)
- Clang no longer emits inappropriate notes about the loss of ``__unaligned`` qualifier

This comment has been minimized.

Copy link
@poyaoc97

poyaoc97 Jul 23, 2023

Member

Is this deletion intended? @AMP999 @cor3ntin

This comment has been minimized.

Copy link
@cor3ntin

cor3ntin Jul 23, 2023

Contributor

No, good catch, I'll fix that right away.

on overload resolution, when the actual reason for the failure is loss of other qualifiers.
- The note emitted when an ``operator==`` was defaulted as deleted used to refer to
the lack of a data member's "three-way comparison operator". It now refers correctly
to the data member's ``operator==``.
(`#63960: <https://github.com/llvm/llvm-project/issues/63960>`_)
- Clang's notes about unconvertible types in overload resolution failure now covers
the source range of parameter declaration of the candidate function declaration.

Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Sema/SemaDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8209,7 +8209,8 @@ class DefaultedComparisonAnalyzer

if (Diagnose == ExplainDeleted) {
S.Diag(Subobj.Loc, diag::note_defaulted_comparison_no_viable_function)
<< FD << (OO == OO_ExclaimEqual) << Subobj.Kind << Subobj.Decl;
<< FD << (OO == OO_EqualEqual || OO == OO_ExclaimEqual)
<< Subobj.Kind << Subobj.Decl;

// For a three-way comparison, list both the candidates for the
// original operator and the candidates for the synthesized operator.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ namespace P1946 {
friend bool operator==(A &, A &); // expected-note {{would lose const qualifier}}
};
struct B {
A a; // expected-note {{no viable three-way comparison}}
A a; // expected-note {{no viable 'operator=='}}
friend bool operator==(B, B) = default; // ok
friend bool operator==(const B&, const B&) = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ namespace DeleteAfterFirstDecl {
struct Q {
struct X {
friend std::strong_ordering operator<=>(const X&, const X&);
} x; // expected-note {{no viable three-way comparison}}
} x; // expected-note {{no viable 'operator=='}}
// 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
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ struct A {
// expected-note@-1 {{defaulted 'operator!=' is implicitly deleted because there is no viable 'operator==' for 'A'}}
};

struct A2 {
struct E {};
E e;
bool operator==(const A2&) const = default; // expected-warning {{explicitly defaulted equality comparison operator is implicitly deleted}} expected-note{{replace 'default'}}
// expected-note@-2 {{defaulted 'operator==' is implicitly deleted because there is no viable 'operator==' for member 'e'}}
};


struct Q {};
bool operator!=(Q, Q); // expected-note {{defaulted 'operator!=' is implicitly deleted because this non-rewritten comparison function would be the best match for the comparison}}
struct B {
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CXX/class/class.compare/class.eq/p2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ struct H3 {
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 three-way comparison function for member 't'}}
T t; // expected-note 3{{because there is no viable 'operator==' for member 't'}}
// expected-note@-1 {{because it would invoke a deleted comparison function for member 't'}}
};

Expand Down
4 changes: 2 additions & 2 deletions clang/test/CXX/class/class.compare/class.spaceship/p1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ namespace Deletedness {
// expected-note@#base {{deleted comparison function for base class 'C'}}
// 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 three-way comparison function for base class 'D2'}}
// expected-note@#base {{no viable 'operator==' 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 @@ -112,7 +112,7 @@ namespace Deletedness {
// expected-note@#arr {{deleted 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 three-way comparison function for member 'arr'}}
// expected-note@#arr {{no viable 'operator==' 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

0 comments on commit 02bb2be

Please sign in to comment.