PR44761: Fix fallback to later tiebreakers if two non-template functions

are equally constrained.
This commit is contained in:
Richard Smith 2020-02-04 12:20:34 -08:00
parent c99fa0b80c
commit cfacf9ae20
2 changed files with 22 additions and 8 deletions

View File

@ -9588,17 +9588,15 @@ bool clang::isBetterOverloadCandidate(
if (RC1 && RC2) {
bool AtLeastAsConstrained1, AtLeastAsConstrained2;
if (S.IsAtLeastAsConstrained(Cand1.Function, {RC1}, Cand2.Function,
{RC2}, AtLeastAsConstrained1))
return false;
if (!AtLeastAsConstrained1)
return false;
if (S.IsAtLeastAsConstrained(Cand2.Function, {RC2}, Cand1.Function,
{RC2}, AtLeastAsConstrained1) ||
S.IsAtLeastAsConstrained(Cand2.Function, {RC2}, Cand1.Function,
{RC1}, AtLeastAsConstrained2))
return false;
if (!AtLeastAsConstrained2)
return true;
} else if (RC1 || RC2)
if (AtLeastAsConstrained1 != AtLeastAsConstrained2)
return AtLeastAsConstrained1;
} else if (RC1 || RC2) {
return RC1 != nullptr;
}
}
}

View File

@ -0,0 +1,16 @@
// RUN: %clang_cc1 -std=c++2a -verify %s
namespace PR44761 {
template<typename T> concept X = (sizeof(T) == sizeof(T));
template<typename T> struct A {
bool operator<(const A&) const & requires X<T>; // #1
int operator<=>(const A&) const & requires X<T> && X<int> = delete; // #2
};
bool k1 = A<int>() < A<int>(); // not ordered by constraints: prefer non-rewritten form
bool k2 = A<float>() < A<float>(); // prefer more-constrained 'operator<=>'
// expected-error@-1 {{deleted}}
// expected-note@#1 {{candidate}}
// expected-note@#2 {{candidate function has been explicitly deleted}}
// expected-note@#2 {{candidate function (with reversed parameter order) has been explicitly deleted}}
}