[clang] Recognize friend operator != to fix ambiguity with operator== (PR #70217)
Utkarsh Saxena via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 26 04:03:07 PDT 2023
https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/70217
>From 26b9570fadf428e2f55efe0f2d9433cf18305239 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena <usx at google.com>
Date: Wed, 25 Oct 2023 16:55:15 +0200
Subject: [PATCH 1/4] friend operator!=
---
clang/lib/Sema/SemaOverload.cpp | 11 +++++----
.../over.match.oper/p3-2a.cpp | 23 +++++++++++++++++++
2 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index db386fef0661c05..ce7503162ef3ba3 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -960,15 +960,18 @@ static bool shouldAddReversedEqEq(Sema &S, SourceLocation OpLoc,
if (FunctionsCorrespond(S.Context, EqFD, Op->getAsFunction()))
return false;
return true;
- }
+ }
// Otherwise the search scope is the namespace scope of which F is a member.
- for (NamedDecl *Op : EqFD->getEnclosingNamespaceContext()->lookup(NotEqOp)) {
+ DeclContext *EqDC = EqFD->getEnclosingNamespaceContext();
+ for (NamedDecl *Op : EqDC->lookup(NotEqOp)) {
auto *NotEqFD = Op->getAsFunction();
+ DeclContext *NotEqDC = Op->getFriendObjectKind()
+ ? NotEqFD->getEnclosingNamespaceContext()
+ : Op->getLexicalDeclContext();
if (auto *UD = dyn_cast<UsingShadowDecl>(Op))
NotEqFD = UD->getUnderlyingDecl()->getAsFunction();
if (FunctionsCorrespond(S.Context, EqFD, NotEqFD) && S.isVisible(NotEqFD) &&
- declaresSameEntity(cast<Decl>(EqFD->getEnclosingNamespaceContext()),
- cast<Decl>(Op->getLexicalDeclContext())))
+ declaresSameEntity(cast<Decl>(EqDC), cast<Decl>(NotEqDC)))
return false;
}
return true;
diff --git a/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp b/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
index d83a176ec07eec9..603c91bd535f434 100644
--- a/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
+++ b/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
@@ -324,6 +324,29 @@ bool x = X() == X(); // expected-warning {{ambiguous}}
}
} // namespace P2468R2
+namespace friend_opNE_GH{
+namespace test1 {
+struct S {
+ operator int();
+ friend bool operator==(const S &, int); // expected-note {{reversed}}
+};
+struct A : S {};
+struct B : S {};
+bool x = A{} == B{}; // expected-warning {{ambiguous}}
+} // namespace test1
+
+namespace test2 {
+struct S {
+ operator int();
+ friend bool operator==(const S &, int);
+ friend bool operator!=(const S &, int);
+};
+struct A : public P {};
+struct B : public P {};
+bool check(A a, B b) { return a == b; } // expected-warning {{use of overloaded operator '==' (with operand types 'A' and 'B') to be ambiguous}}
+} // namespace test2
+} // namespace friend_opNE_GH
+
namespace ADL_GH68901{
namespace test1 {
namespace A {
>From 538c4e2d0244b2da4f0023bc17768448d728b6ce Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena <usx at google.com>
Date: Wed, 25 Oct 2023 16:57:01 +0200
Subject: [PATCH 2/4] remove space
---
clang/lib/Sema/SemaOverload.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index ce7503162ef3ba3..3b6b474886340eb 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -960,7 +960,7 @@ static bool shouldAddReversedEqEq(Sema &S, SourceLocation OpLoc,
if (FunctionsCorrespond(S.Context, EqFD, Op->getAsFunction()))
return false;
return true;
- }
+ }
// Otherwise the search scope is the namespace scope of which F is a member.
DeclContext *EqDC = EqFD->getEnclosingNamespaceContext();
for (NamedDecl *Op : EqDC->lookup(NotEqOp)) {
>From a78d5b4b8d8a04741f0ca090625179b254e10ef5 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena <usx at google.com>
Date: Wed, 25 Oct 2023 16:59:19 +0200
Subject: [PATCH 3/4] rename namespaces
---
.../over.match.funcs/over.match.oper/p3-2a.cpp | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp b/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
index 603c91bd535f434..fb354087189cc2f 100644
--- a/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
+++ b/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
@@ -325,7 +325,7 @@ bool x = X() == X(); // expected-warning {{ambiguous}}
} // namespace P2468R2
namespace friend_opNE_GH{
-namespace test1 {
+namespace opNENotFound {
struct S {
operator int();
friend bool operator==(const S &, int); // expected-note {{reversed}}
@@ -333,9 +333,9 @@ struct S {
struct A : S {};
struct B : S {};
bool x = A{} == B{}; // expected-warning {{ambiguous}}
-} // namespace test1
+} // namespace opNENotFound
-namespace test2 {
+namespace opNEFound {
struct S {
operator int();
friend bool operator==(const S &, int);
@@ -343,8 +343,8 @@ struct S {
};
struct A : public P {};
struct B : public P {};
-bool check(A a, B b) { return a == b; } // expected-warning {{use of overloaded operator '==' (with operand types 'A' and 'B') to be ambiguous}}
-} // namespace test2
+bool x = A{} == B{};
+} // namespace opNEFound
} // namespace friend_opNE_GH
namespace ADL_GH68901{
>From 56fdcb76186c11c00934148c0bafbc9946b373e3 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena <usx at google.com>
Date: Thu, 26 Oct 2023 13:02:51 +0200
Subject: [PATCH 4/4] fix tests
---
.../over.match/over.match.funcs/over.match.oper/p3-2a.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp b/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
index fb354087189cc2f..3a33614a5cc340f 100644
--- a/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
+++ b/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
@@ -341,8 +341,8 @@ struct S {
friend bool operator==(const S &, int);
friend bool operator!=(const S &, int);
};
-struct A : public P {};
-struct B : public P {};
+struct A : S {};
+struct B : S {};
bool x = A{} == B{};
} // namespace opNEFound
} // namespace friend_opNE_GH
More information about the cfe-commits
mailing list