Skip to content

Commit e6d0b12

Browse files
authored
Correctly compute conversion seq for args to fn with reversed param order (#68999)
We associated conversion seq for args (when reversed) to the wrong index. This lead to clang believing reversed `operator==` a worse overload candidate than the `operator==` without reversed args when both these candidate were ambiguous. Fixes #53954
1 parent 3151281 commit e6d0b12

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ C++ Language Changes
117117

118118
C++20 Feature Support
119119
^^^^^^^^^^^^^^^^^^^^^
120+
- Fix a bug in conversion sequence of arguments to a function with reversed parameter order.
121+
Fixes `GH <https://github.com/llvm/llvm-project/issues/53954>`_.
120122

121123
C++23 Feature Support
122124
^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaOverload.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7688,7 +7688,7 @@ bool Sema::CheckNonDependentConversions(
76887688
QualType ParamType = ParamTypes[I + Offset];
76897689
if (!ParamType->isDependentType()) {
76907690
unsigned ConvIdx = PO == OverloadCandidateParamOrder::Reversed
7691-
? 0
7691+
? Args.size() - 1 - (ThisConversions + I)
76927692
: (ThisConversions + I);
76937693
Conversions[ConvIdx]
76947694
= TryCopyInitialization(*this, Args[I], ParamType,

clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,41 @@ bool x = X() == X(); // expected-warning {{ambiguous}}
324324
}
325325
} // namespace P2468R2
326326

327+
namespace GH53954{
328+
namespace test1 {
329+
struct P {
330+
template <class T>
331+
friend bool operator==(const P&, const T&); // expected-note {{candidate}} \
332+
// expected-note {{reversed parameter order}}
333+
};
334+
struct A : public P {};
335+
struct B : public P {};
336+
bool check(A a, B b) { return a == b; } // expected-error {{ '==' is ambiguous}}
337+
}
338+
339+
namespace test2 {
340+
struct P {
341+
template <class T>
342+
friend bool operator==(const T&, const P&); // expected-note {{candidate}} \
343+
// expected-note {{reversed parameter order}}
344+
};
345+
struct A : public P {};
346+
struct B : public P {};
347+
bool check(A a, B b) { return a == b; } // expected-error {{ '==' is ambiguous}}
348+
}
349+
350+
namespace test3 {
351+
struct P {
352+
template<class S>
353+
bool operator==(const S &) const; // expected-note {{candidate}} \
354+
// expected-note {{reversed parameter order}}
355+
};
356+
struct A : public P {};
357+
struct B : public P {};
358+
bool check(A a, B b) { return a == b; } // expected-error {{ '==' is ambiguous}}
359+
}
360+
}
361+
327362
#else // NO_ERRORS
328363

329364
namespace problem_cases {

0 commit comments

Comments
 (0)