[clang] Correctly compute conversion seq for args to fn with reversed param order (PR #68999)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 13 08:24:14 PDT 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Utkarsh Saxena (usx95)
<details>
<summary>Changes</summary>
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 https://github.com/llvm/llvm-project/issues/53954
---
Full diff: https://github.com/llvm/llvm-project/pull/68999.diff
3 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+2)
- (modified) clang/lib/Sema/SemaOverload.cpp (+2-2)
- (modified) clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp (+35)
``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2d918967e7f0b02..07cedeabcdbd9b7 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -113,6 +113,8 @@ C++ Language Changes
C++20 Feature Support
^^^^^^^^^^^^^^^^^^^^^
+- Fix a bug in conversion sequence of arguments to a function with reversed parameter order.
+ Fixes `GH <https://github.com/llvm/llvm-project/issues/53954>`_.
C++23 Feature Support
^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index ce78994e6553814..b00adb00eab01aa 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -7688,7 +7688,7 @@ bool Sema::CheckNonDependentConversions(
QualType ParamType = ParamTypes[I + Offset];
if (!ParamType->isDependentType()) {
unsigned ConvIdx = PO == OverloadCandidateParamOrder::Reversed
- ? 0
+ ? Args.size() - 1 - (ThisConversions + I)
: (ThisConversions + I);
Conversions[ConvIdx]
= TryCopyInitialization(*this, Args[I], ParamType,
@@ -10631,7 +10631,7 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc,
// Find the best viable function.
Best = end();
for (auto *Cand : Candidates) {
- Cand->Best = false;
+ Cand->Best = false;
if (Cand->Viable) {
if (Best == end() ||
isBetterOverloadCandidate(S, *Cand, *Best, Loc, Kind))
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 5c6804eb7726b5f..8975706e721cff1 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,41 @@ bool x = X() == X(); // expected-warning {{ambiguous}}
}
} // namespace P2468R2
+namespace GH53954{
+namespace test1 {
+struct P {
+ template <class S>
+ friend bool operator==(const P &, const S &); // expected-note {{candidate}} \
+ // expected-note {{reversed parameter order}}
+};
+struct A : public P {};
+struct B : public P {};
+bool check(A a, B b) { return a == b; } // expected-error {{ '==' is ambiguous}}
+}
+
+namespace test2 {
+struct P {
+ template <class S>
+ friend bool operator==(const S &, const P &); // expected-note {{candidate}} \
+ // expected-note {{reversed parameter order}}
+};
+struct A : public P {};
+struct B : public P {};
+bool check(A a, B b) { return a == b; } // expected-error {{ '==' is ambiguous}}
+}
+
+namespace test3 {
+struct P {
+ template<class S>
+ bool operator==(const S &) const; // expected-note {{candidate}} \
+ // expected-note {{reversed parameter order}}
+};
+struct A : public P {};
+struct B : public P {};
+bool check(A a, B b) { return a == b; } // expected-error {{ '==' is ambiguous}}
+}
+}
+
#else // NO_ERRORS
namespace problem_cases {
``````````
</details>
https://github.com/llvm/llvm-project/pull/68999
More information about the cfe-commits
mailing list