From 1b77e73ef6b7ed886abbc79b89fcb59b0e5c69a1 Mon Sep 17 00:00:00 2001 From: John McCall Date: Fri, 15 Jan 2010 23:32:50 +0000 Subject: [PATCH] Candidates with arity mismatches are extra-special non-viable and need to stand at the back of the line. Thanks to Oliver Hunt for reminding me to do this. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93583 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaOverload.cpp | 48 ++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 6ec4d1b600..e4168eb7c8 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -4582,6 +4582,14 @@ void NoteAmbiguousUserConversions(Sema &S, SourceLocation OpLoc, } } +SourceLocation GetLocationForCandidate(const OverloadCandidate *Cand) { + if (Cand->Function) + return Cand->Function->getLocation(); + if (Cand->Surrogate) + return Cand->Surrogate->getLocation(); + return SourceLocation(); +} + struct CompareOverloadCandidatesForDisplay { Sema &S; CompareOverloadCandidatesForDisplay(Sema &S) : S(S) {} @@ -4600,22 +4608,30 @@ struct CompareOverloadCandidatesForDisplay { } else if (R->Viable) return false; - // Put declared functions first. - if (L->Function) { - if (!R->Function) return true; - return S.SourceMgr.isBeforeInTranslationUnit(L->Function->getLocation(), - R->Function->getLocation()); - } else if (R->Function) return false; - - // Then surrogates. - if (L->IsSurrogate) { - if (!R->IsSurrogate) return true; - return S.SourceMgr.isBeforeInTranslationUnit(L->Surrogate->getLocation(), - R->Surrogate->getLocation()); - } else if (R->IsSurrogate) return false; - - // And builtins just come in a jumble. - return false; + assert(L->Viable == R->Viable); + + // Criteria by which we can sort non-viable candidates: + 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) + return false; + if (R->FailureKind == ovl_fail_too_many_arguments || + R->FailureKind == ovl_fail_too_few_arguments) + return true; + + // TODO: others? + } + + // Sort everything else by location. + SourceLocation LLoc = GetLocationForCandidate(L); + SourceLocation RLoc = GetLocationForCandidate(R); + + // Put candidates without locations (e.g. builtins) at the end. + if (LLoc.isInvalid()) return false; + if (RLoc.isInvalid()) return true; + + return S.SourceMgr.isBeforeInTranslationUnit(LLoc, RLoc); } }; -- 2.50.1