Unverified Commit e6d0b126 authored by Utkarsh Saxena's avatar Utkarsh Saxena Committed by GitHub
Browse files

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 https://github.com/llvm/llvm-project/issues/53954
parent 31512811
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -117,6 +117,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
^^^^^^^^^^^^^^^^^^^^^
+1 −1
Original line number Diff line number Diff line
@@ -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,
+35 −0
Original line number Diff line number Diff line
@@ -324,6 +324,41 @@ bool x = X() == X(); // expected-warning {{ambiguous}}
}
} // namespace P2468R2

namespace GH53954{
namespace test1 {
struct P {
    template <class T>
    friend bool operator==(const P&, const T&); // 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 T>
    friend bool operator==(const T&, 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 {