]> granicus.if.org Git - clang/commitdiff
When sorting overload candidates, sort arity mismatches in ascending
authorKaelyn Takata <rikka@google.com>
Thu, 1 May 2014 21:15:24 +0000 (21:15 +0000)
committerKaelyn Takata <rikka@google.com>
Thu, 1 May 2014 21:15:24 +0000 (21:15 +0000)
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

lib/Sema/SemaOverload.cpp
test/Misc/error-limit-multiple-notes.cpp

index 1f2875cd6ffcbf291e3cbd9db8c672c4f4a5490a..0ae9b79f008080611b99488946aa46313109bf7b 100644 (file)
@@ -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;
 
index 71a39091f60cfe7f9e52a29c163d7604857e8ab4..a0c3967ff5bf4a767dc505fff2bc0765265a9cee 100644 (file)
@@ -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