More fixes for isBetterOverloadCandidate not being a strict weak ordering. The

bug was obvious from inspection, figuring out a way to test it was... less so.

llvm-svn: 209060
This commit is contained in:
Richard Smith 2014-05-17 04:36:39 +00:00
parent d4d5534034
commit ec2748a8ad
2 changed files with 26 additions and 19 deletions

View File

@ -8250,26 +8250,15 @@ isBetterOverloadCandidate(Sema &S,
// other. This only distinguishes the results in non-standard, extension
// cases such as the conversion from a lambda closure type to a function
// pointer or block.
ImplicitConversionSequence::CompareKind FuncResult
= compareConversionFunctions(S, Cand1.Function, Cand2.Function);
if (FuncResult != ImplicitConversionSequence::Indistinguishable)
return FuncResult;
ImplicitConversionSequence::CompareKind Result =
compareConversionFunctions(S, Cand1.Function, Cand2.Function);
if (Result == ImplicitConversionSequence::Indistinguishable)
Result = CompareStandardConversionSequences(S,
Cand1.FinalConversion,
Cand2.FinalConversion);
switch (CompareStandardConversionSequences(S,
Cand1.FinalConversion,
Cand2.FinalConversion)) {
case ImplicitConversionSequence::Better:
// Cand1 has a better conversion sequence.
return true;
case ImplicitConversionSequence::Worse:
// Cand1 can't be better than Cand2.
return false;
case ImplicitConversionSequence::Indistinguishable:
// Do nothing
break;
}
if (Result != ImplicitConversionSequence::Indistinguishable)
return Result == ImplicitConversionSequence::Better;
// FIXME: Compare kind of reference binding if conversion functions
// convert to a reference type used in direct reference binding, per

View File

@ -85,6 +85,24 @@ namespace overloading {
void call_with_lambda() {
int &ir = accept_lambda_conv([](int x) { return x + 1; });
}
template<typename T> using id = T;
auto a = [](){};
struct C : decltype(a) {
using decltype(a)::operator id<void(*)()>;
private:
using decltype(a)::operator id<void(^)()>;
} extern c;
struct D : decltype(a) {
using decltype(a)::operator id<void(^)()>;
private:
using decltype(a)::operator id<void(*)()>; // expected-note {{here}}
} extern d;
bool r1 = c;
bool r2 = d; // expected-error {{private}}
}
namespace PR13117 {