diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 1f2875cd6ffc..0ae9b79f0080 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/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/clang/test/Misc/error-limit-multiple-notes.cpp b/clang/test/Misc/error-limit-multiple-notes.cpp index 71a39091f60c..a0c3967ff5bf 100644 --- a/clang/test/Misc/error-limit-multiple-notes.cpp +++ b/clang/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