From: Kaelyn Takata Date: Thu, 1 May 2014 21:15:24 +0000 (+0000) Subject: When sorting overload candidates, sort arity mismatches in ascending X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8603e9ecdce78925e5186a29c4a628cecc662c34;p=clang When sorting overload candidates, sort arity mismatches in ascending order by the number of missing or extra parameters. This is useful if there are more than a few overload candidates with arity mismatches, particularly in the presence of -fshow-overloads=best. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@207796 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 1f2875cd6f..0ae9b79f00 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -9229,7 +9229,10 @@ static unsigned RankDeductionFailure(const DeductionFailureInfo &DFI) { struct CompareOverloadCandidatesForDisplay { Sema &S; - CompareOverloadCandidatesForDisplay(Sema &S) : S(S) {} + size_t NumArgs; + + CompareOverloadCandidatesForDisplay(Sema &S, size_t nArgs) + : S(S), NumArgs(nArgs) {} bool operator()(const OverloadCandidate *L, const OverloadCandidate *R) { @@ -9254,8 +9257,18 @@ struct CompareOverloadCandidatesForDisplay { if (!L->Viable) { // 1. Arity mismatches come after other candidates. if (L->FailureKind == ovl_fail_too_many_arguments || - L->FailureKind == ovl_fail_too_few_arguments) + L->FailureKind == ovl_fail_too_few_arguments) { + if (R->FailureKind == ovl_fail_too_many_arguments || + R->FailureKind == ovl_fail_too_few_arguments) { + int LDist = abs(L->Function->getNumParams() - NumArgs); + int RDist = abs(R->Function->getNumParams() - NumArgs); + if (LDist == RDist) + return L->FailureKind == ovl_fail_too_many_arguments && + R->FailureKind == ovl_fail_too_few_arguments; + return LDist < RDist; + } return false; + } if (R->FailureKind == ovl_fail_too_many_arguments || R->FailureKind == ovl_fail_too_few_arguments) return true; @@ -9442,7 +9455,7 @@ void OverloadCandidateSet::NoteCandidates(Sema &S, } std::sort(Cands.begin(), Cands.end(), - CompareOverloadCandidatesForDisplay(S)); + CompareOverloadCandidatesForDisplay(S, Args.size())); bool ReportedAmbiguousConversions = false; diff --git a/test/Misc/error-limit-multiple-notes.cpp b/test/Misc/error-limit-multiple-notes.cpp index 71a39091f6..a0c3967ff5 100644 --- a/test/Misc/error-limit-multiple-notes.cpp +++ b/test/Misc/error-limit-multiple-notes.cpp @@ -4,20 +4,22 @@ void foo(int); void foo(double); void foo(int, int); +void foo(int, int, int, int); int main() { - foo(); + foo(1, 2, 3); } // error and note suppressed by error-limit struct s1{}; struct s1{}; -// CHECK: 10:5: error: no matching function for call to 'foo' -// CHECK: 6:6: note: candidate function not viable: requires 2 arguments, but 0 were provided -// CHECK: 5:6: note: candidate function not viable: requires 1 argument, but 0 were provided -// CHECK: 4:6: note: candidate function not viable: requires 1 argument, but 0 were provided +// CHECK: 11:5: error: no matching function for call to 'foo' +// CHECK: 6:6: note: candidate function not viable: requires 2 arguments, but 3 were provided +// CHECK: 7:6: note: candidate function not viable: requires 4 arguments, but 3 were provided +// CHECK: 5:6: note: candidate function not viable: requires 1 argument, but 3 were provided +// CHECK: 4:6: note: candidate function not viable: requires 1 argument, but 3 were provided // CHECK: fatal error: too many errors emitted, stopping now -// CHECK-NOT: 15:8: error: redefinition of 's1' -// CHECK-NOT: 14:8: note: previous definition is here +// CHECK-NOT: 16:8: error: redefinition of 's1' +// CHECK-NOT: 15:8: note: previous definition is here