[clang] Correctly compute conversion seq for args to fn with reversed param order (PR #68999)

Utkarsh Saxena via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 13 08:25:06 PDT 2023


https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/68999

>From 01ba05ec9349c7b93239b7e6196e3fa6c7fc1f82 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena <usx at google.com>
Date: Fri, 13 Oct 2023 17:17:32 +0200
Subject: [PATCH 1/2] Correctly compute conversion seq for args to fn with
 reveresed param order

---
 clang/docs/ReleaseNotes.rst                   |  2 ++
 clang/lib/Sema/SemaOverload.cpp               |  4 +--
 .../over.match.oper/p3-2a.cpp                 | 35 +++++++++++++++++++
 3 files changed, 39 insertions(+), 2 deletions(-)

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 {

>From 74712023035fe4d670306776d9808bed91fe4ba3 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena <usx at google.com>
Date: Fri, 13 Oct 2023 17:24:34 +0200
Subject: [PATCH 2/2] add more tests

---
 .../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 8975706e721cff1..02fe37dc1be5058 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
@@ -327,8 +327,8 @@ bool x = X() == X(); // expected-warning {{ambiguous}}
 namespace GH53954{
 namespace test1 {
 struct P {
-    template <class S>
-    friend bool operator==(const P &, const S &); // expected-note {{candidate}} \
+    template <class T>
+    friend bool operator==(const P&, const T&); // expected-note {{candidate}} \
                                                   // expected-note {{reversed parameter order}}
 };
 struct A : public P {};
@@ -338,9 +338,9 @@ 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}}
+    template <class T>
+    friend bool operator==(const T&, const P&); // expected-note {{candidate}} \
+                                                // expected-note {{reversed parameter order}}
 };
 struct A : public P {};
 struct B : public P {};



More information about the cfe-commits mailing list