diff options
| author | Kaelyn Takata <rikka@google.com> | 2014-05-07 00:43:38 +0000 |
|---|---|---|
| committer | Kaelyn Takata <rikka@google.com> | 2014-05-07 00:43:38 +0000 |
| commit | 50c4ffcca78e080bb5f0a98f09f4af44520381a9 (patch) | |
| tree | 8f993320a65db6aabebd432712359bbf9d94440c | |
| parent | d6a0604180fb6289c7a64d0dc9e5d9826bb5928b (diff) | |
| download | bcm5719-llvm-50c4ffcca78e080bb5f0a98f09f4af44520381a9.tar.gz bcm5719-llvm-50c4ffcca78e080bb5f0a98f09f4af44520381a9.zip | |
Try harder to ensure a strict weak ordering of overload candidates that
have arity mismatches.
llvm-svn: 208146
| -rw-r--r-- | clang/include/clang/Sema/Overload.h | 12 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 17 |
2 files changed, 23 insertions, 6 deletions
diff --git a/clang/include/clang/Sema/Overload.h b/clang/include/clang/Sema/Overload.h index d6dbd1226a8..9618f8f1086 100644 --- a/clang/include/clang/Sema/Overload.h +++ b/clang/include/clang/Sema/Overload.h @@ -679,6 +679,18 @@ namespace clang { return CanFix; } + + unsigned getNumParams() const { + if (IsSurrogate) { + auto STy = Surrogate->getConversionType(); + while (STy->isPointerType() || STy->isReferenceType()) + STy = STy->getPointeeType(); + return STy->getAs<FunctionProtoType>()->getNumParams(); + } + if (Function) + return Function->getNumParams(); + return ExplicitCallArguments; + } }; /// OverloadCandidateSet - A set of overload candidates, used in C++ diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 7f9e0ecd96f..51d130c685e 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -9260,12 +9260,17 @@ struct CompareOverloadCandidatesForDisplay { L->FailureKind == ovl_fail_too_few_arguments) { if (R->FailureKind == ovl_fail_too_many_arguments || R->FailureKind == ovl_fail_too_few_arguments) { - if (!L->Function || !R->Function) return !R->Function; - int LDist = std::abs((int)L->Function->getNumParams() - (int)NumArgs); - int RDist = std::abs((int)R->Function->getNumParams() - (int)NumArgs); - if (LDist == RDist) - return L->FailureKind == ovl_fail_too_many_arguments && - R->FailureKind == ovl_fail_too_few_arguments; + int LDist = std::abs((int)L->getNumParams() - (int)NumArgs); + int RDist = std::abs((int)R->getNumParams() - (int)NumArgs); + if (LDist == RDist) { + if (L->FailureKind == R->FailureKind) + // Sort non-surrogates before surrogates. + return !L->IsSurrogate && R->IsSurrogate; + // Sort candidates requiring fewer parameters than there were + // arguments given after candidates requiring more parameters + // than there were arguments given. + return L->FailureKind == ovl_fail_too_many_arguments; + } return LDist < RDist; } return false; |

