diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -950,7 +950,10 @@ LookupResult Members(S, NotEqOp, OpLoc, Sema::LookupNameKind::LookupMemberName); S.LookupQualifiedName(Members, RHSRec->getDecl()); - Members.suppressAccessDiagnostics(); + // According to [over.match.oper]p4 we should run "search" and not "lookup" + // for reversed operators, so suppress diagnostics. + Members.suppressDiagnostics(); + for (NamedDecl *Op : Members) if (FunctionsCorrespond(S.Context, EqFD, Op->getAsFunction())) return false; diff --git a/clang/test/SemaCXX/cxx20-reversed-operators-search.cpp b/clang/test/SemaCXX/cxx20-reversed-operators-search.cpp new file mode 100644 --- /dev/null +++ b/clang/test/SemaCXX/cxx20-reversed-operators-search.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s +// expected-no-diagnostics + + +namespace members { + +struct X { + virtual ~X(); + virtual bool operator ==(X); + bool operator !=(X); +}; + +struct Y { + virtual ~Y(); + virtual bool operator ==(Y); + bool operator !=(Y); +}; + +struct Z : X, Y { + virtual bool operator==(Z); + bool operator==(X) override; + bool operator==(Y) override; +}; + +void test() { + bool b = Z() == Z(); +} + +} // namespace members +