[clang] 70f59b5 - When diagnosing an ambiguity, only note the candidates that contribute

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 24 14:58:41 PDT 2019


Author: Richard Smith
Date: 2019-10-24T14:58:29-07:00
New Revision: 70f59b5bbc84d195b4c7ee1597dcae4e73d3c479

URL: https://github.com/llvm/llvm-project/commit/70f59b5bbc84d195b4c7ee1597dcae4e73d3c479
DIFF: https://github.com/llvm/llvm-project/commit/70f59b5bbc84d195b4c7ee1597dcae4e73d3c479.diff

LOG: When diagnosing an ambiguity, only note the candidates that contribute
to the ambiguity, rather than noting all viable candidates.

Added: 
    

Modified: 
    clang/include/clang/Sema/Overload.h
    clang/lib/Sema/SemaCast.cpp
    clang/lib/Sema/SemaExprCXX.cpp
    clang/lib/Sema/SemaInit.cpp
    clang/lib/Sema/SemaOverload.cpp
    clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp
    clang/test/CXX/drs/dr15xx.cpp
    clang/test/CXX/drs/dr16xx.cpp
    clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p3.cpp
    clang/test/CXX/special/class.inhctor/p1.cpp
    clang/test/CXX/special/class.inhctor/p4.cpp
    clang/test/CXX/special/class.inhctor/p7.cpp
    clang/test/SemaCXX/ambig-user-defined-conversions.cpp
    clang/test/SemaCXX/builtin-ptrtomember-ambig.cpp
    clang/test/SemaCXX/builtin-ptrtomember-overload-1.cpp
    clang/test/SemaCXX/copy-initialization.cpp
    clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
    clang/test/SemaCXX/microsoft-vs-float128.cpp
    clang/test/SemaCXX/overload-call.cpp
    clang/test/SemaCXX/overload-member-call.cpp
    clang/test/SemaCXX/overloaded-builtin-operators.cpp
    clang/test/SemaTemplate/cxx1z-using-declaration.cpp
    clang/test/SemaTemplate/instantiate-expr-3.cpp
    clang/test/SemaTemplate/temp_arg_nontype.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Sema/Overload.h b/clang/include/clang/Sema/Overload.h
index a97a7181f7d5..728a596a92f1 100644
--- a/clang/include/clang/Sema/Overload.h
+++ b/clang/include/clang/Sema/Overload.h
@@ -68,7 +68,10 @@ class Sema;
     OCD_AllCandidates,
 
     /// Requests that only viable candidates be shown.
-    OCD_ViableCandidates
+    OCD_ViableCandidates,
+
+    /// Requests that only tied-for-best candidates be shown.
+    OCD_AmbiguousCandidates
   };
 
   /// The parameter ordering that will be used for the candidate. This is
@@ -791,6 +794,15 @@ class Sema;
     /// Viable - True to indicate that this overload candidate is viable.
     bool Viable : 1;
 
+    /// Whether this candidate is the best viable function, or tied for being
+    /// the best viable function.
+    ///
+    /// For an ambiguous overload resolution, indicates whether this candidate
+    /// was part of the ambiguity kernel: the minimal non-empty set of viable
+    /// candidates such that all elements of the ambiguity kernel are better
+    /// than all viable candidates not in the ambiguity kernel.
+    bool Best : 1;
+
     /// IsSurrogate - True to indicate that this candidate is a
     /// surrogate for a conversion to a function pointer or reference
     /// (C++ [over.call.object]).

diff  --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index 0ebb5c68f7c2..2ab0a11e5329 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -423,7 +423,7 @@ static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT,
 
   case OR_Ambiguous:
     msg = diag::err_ovl_ambiguous_conversion_in_cast;
-    howManyCandidates = OCD_ViableCandidates;
+    howManyCandidates = OCD_AmbiguousCandidates;
     break;
 
   case OR_Deleted:

diff  --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 9aae9289b514..18efd8335d9d 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -2323,7 +2323,7 @@ static bool resolveAllocationOverload(
           PartialDiagnosticAt(R.getNameLoc(),
                               S.PDiag(diag::err_ovl_ambiguous_call)
                                   << R.getLookupName() << Range),
-          S, OCD_ViableCandidates, Args);
+          S, OCD_AmbiguousCandidates, Args);
     }
     return true;
 
@@ -3513,7 +3513,7 @@ static bool resolveBuiltinNewDeleteOverload(Sema &S, CallExpr *TheCall,
         PartialDiagnosticAt(R.getNameLoc(),
                             S.PDiag(diag::err_ovl_ambiguous_call)
                                 << R.getLookupName() << Range),
-        S, OCD_ViableCandidates, Args);
+        S, OCD_AmbiguousCandidates, Args);
     return true;
 
   case OR_Deleted: {

diff  --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 10cb7acad567..1296e767ff0b 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -6154,7 +6154,7 @@ static ExprResult CopyObject(Sema &S,
                                      << (int)Entity.getKind()
                                      << CurInitExpr->getType()
                                      << CurInitExpr->getSourceRange()),
-        S, OCD_ViableCandidates, CurInitExpr);
+        S, OCD_AmbiguousCandidates, CurInitExpr);
     return ExprError();
 
   case OR_Deleted:
@@ -6295,7 +6295,7 @@ static void CheckCXX98CompatAccessibleCopy(Sema &S,
 
   case OR_Ambiguous:
     CandidateSet.NoteCandidates(PartialDiagnosticAt(Loc, Diag), S,
-                                OCD_ViableCandidates, CurInitExpr);
+                                OCD_AmbiguousCandidates, CurInitExpr);
     break;
 
   case OR_Deleted:
@@ -8806,7 +8806,7 @@ bool InitializationSequence::Diagnose(Sema &S,
                   : (S.PDiag(diag::err_ref_init_ambiguous)
                      << DestType << OnlyArg->getType()
                      << Args[0]->getSourceRange())),
-          S, OCD_ViableCandidates, Args);
+          S, OCD_AmbiguousCandidates, Args);
       break;
 
     case OR_No_Viable_Function: {
@@ -9000,7 +9000,7 @@ bool InitializationSequence::Diagnose(Sema &S,
             PartialDiagnosticAt(Kind.getLocation(),
                                 S.PDiag(diag::err_ovl_ambiguous_init)
                                     << DestType << ArgsRange),
-            S, OCD_ViableCandidates, Args);
+            S, OCD_AmbiguousCandidates, Args);
         break;
 
       case OR_No_Viable_Function:
@@ -9863,7 +9863,7 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
             Kind.getLocation(),
             PDiag(diag::err_deduced_class_template_ctor_ambiguous)
                 << TemplateName),
-        *this, OCD_ViableCandidates, Inits);
+        *this, OCD_AmbiguousCandidates, Inits);
     return QualType();
 
   case OR_No_Viable_Function: {

diff  --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index b79855a6afb3..4417d22d133e 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -1357,7 +1357,7 @@ TryUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
     ICS.Ambiguous.setToType(ToType);
     for (OverloadCandidateSet::iterator Cand = Conversions.begin();
          Cand != Conversions.end(); ++Cand)
-      if (Cand->Viable)
+      if (Cand->Best)
         ICS.Ambiguous.addConversion(Cand->FoundDecl, Cand->Function);
     break;
 
@@ -3578,7 +3578,10 @@ Sema::DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType) {
         (OvResult == OR_No_Viable_Function && !CandidateSet.empty())))
     return false;
 
-  auto Cands = CandidateSet.CompleteCandidates(*this, OCD_AllCandidates, From);
+  auto Cands = CandidateSet.CompleteCandidates(
+      *this,
+      OvResult == OR_Ambiguous ? OCD_AmbiguousCandidates : OCD_AllCandidates,
+      From);
   if (OvResult == OR_Ambiguous)
     Diag(From->getBeginLoc(), diag::err_typecheck_ambiguous_condition)
         << From->getType() << ToType << From->getSourceRange();
@@ -4602,7 +4605,7 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS,
     ICS.setAmbiguous();
     for (OverloadCandidateSet::iterator Cand = CandidateSet.begin();
          Cand != CandidateSet.end(); ++Cand)
-      if (Cand->Viable)
+      if (Cand->Best)
         ICS.Ambiguous.addConversion(Cand->FoundDecl, Cand->Function);
     return true;
 
@@ -9653,11 +9656,13 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc,
 
   // Find the best viable function.
   Best = end();
-  for (auto *Cand : Candidates)
+  for (auto *Cand : Candidates) {
+    Cand->Best = false;
     if (Cand->Viable)
       if (Best == end() ||
           isBetterOverloadCandidate(S, *Cand, *Best, Loc, Kind))
         Best = Cand;
+  }
 
   // If we didn't find any viable functions, abort.
   if (Best == end())
@@ -9665,22 +9670,33 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc,
 
   llvm::SmallVector<const NamedDecl *, 4> EquivalentCands;
 
+  llvm::SmallVector<OverloadCandidate*, 4> PendingBest;
+  PendingBest.push_back(&*Best);
+  Best->Best = true;
+
   // Make sure that this function is better than every other viable
   // function. If not, we have an ambiguity.
-  for (auto *Cand : Candidates) {
-    if (Cand->Viable && Cand != Best &&
-        !isBetterOverloadCandidate(S, *Best, *Cand, Loc, Kind)) {
-      if (S.isEquivalentInternalLinkageDeclaration(Best->Function,
-                                                   Cand->Function)) {
-        EquivalentCands.push_back(Cand->Function);
-        continue;
+  while (!PendingBest.empty()) {
+    auto *Curr = PendingBest.pop_back_val();
+    for (auto *Cand : Candidates) {
+      if (Cand->Viable && !Cand->Best &&
+          !isBetterOverloadCandidate(S, *Curr, *Cand, Loc, Kind)) {
+        PendingBest.push_back(Cand);
+        Cand->Best = true;
+
+        if (S.isEquivalentInternalLinkageDeclaration(Cand->Function,
+                                                     Curr->Function))
+          EquivalentCands.push_back(Cand->Function);
+        else
+          Best = end();
       }
-
-      Best = end();
-      return OR_Ambiguous;
     }
   }
 
+  // If we found more than one best candidate, this is ambiguous.
+  if (Best == end())
+    return OR_Ambiguous;
+
   // Best is the best viable function.
   if (Best->Function && Best->Function->isDeleted())
     return OR_Deleted;
@@ -11080,15 +11096,30 @@ SmallVector<OverloadCandidate *, 32> OverloadCandidateSet::CompleteCandidates(
   for (iterator Cand = begin(), LastCand = end(); Cand != LastCand; ++Cand) {
     if (!Filter(*Cand))
       continue;
-    if (Cand->Viable)
-      Cands.push_back(Cand);
-    else if (OCD == OCD_AllCandidates) {
-      CompleteNonViableCandidate(S, Cand, Args, Kind);
-      if (Cand->Function || Cand->IsSurrogate)
-        Cands.push_back(Cand);
-      // Otherwise, this a non-viable builtin candidate.  We do not, in general,
-      // want to list every possible builtin candidate.
+    switch (OCD) {
+    case OCD_AllCandidates:
+      if (!Cand->Viable) {
+        if (!Cand->Function && !Cand->IsSurrogate) {
+          // This a non-viable builtin candidate.  We do not, in general,
+          // want to list every possible builtin candidate.
+          continue;
+        }
+        CompleteNonViableCandidate(S, Cand, Args, Kind);
+      }
+      break;
+
+    case OCD_ViableCandidates:
+      if (!Cand->Viable)
+        continue;
+      break;
+
+    case OCD_AmbiguousCandidates:
+      if (!Cand->Best)
+        continue;
+      break;
     }
+
+    Cands.push_back(Cand);
   }
 
   llvm::stable_sort(
@@ -12453,7 +12484,7 @@ static ExprResult FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
         PartialDiagnosticAt(Fn->getBeginLoc(),
                             SemaRef.PDiag(diag::err_ovl_ambiguous_call)
                                 << ULE->getName() << Fn->getSourceRange()),
-        SemaRef, OCD_ViableCandidates, Args);
+        SemaRef, OCD_AmbiguousCandidates, Args);
     break;
 
   case OR_Deleted: {
@@ -12699,7 +12730,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
                             PDiag(diag::err_ovl_ambiguous_oper_unary)
                                 << UnaryOperator::getOpcodeStr(Opc)
                                 << Input->getType() << Input->getSourceRange()),
-        *this, OCD_ViableCandidates, ArgsArray,
+        *this, OCD_AmbiguousCandidates, ArgsArray,
         UnaryOperator::getOpcodeStr(Opc), OpLoc);
     return ExprError();
 
@@ -13108,7 +13139,7 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
                                          << Args[1]->getType()
                                          << Args[0]->getSourceRange()
                                          << Args[1]->getSourceRange()),
-          *this, OCD_ViableCandidates, Args, BinaryOperator::getOpcodeStr(Opc),
+          *this, OCD_AmbiguousCandidates, Args, BinaryOperator::getOpcodeStr(Opc),
           OpLoc);
       return ExprError();
 
@@ -13293,7 +13324,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
                                         << Args[1]->getType()
                                         << Args[0]->getSourceRange()
                                         << Args[1]->getSourceRange()),
-          *this, OCD_ViableCandidates, Args, "[]", LLoc);
+          *this, OCD_AmbiguousCandidates, Args, "[]", LLoc);
       return ExprError();
 
     case OR_Deleted:
@@ -13485,7 +13516,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
           PartialDiagnosticAt(UnresExpr->getMemberLoc(),
                               PDiag(diag::err_ovl_ambiguous_member_call)
                                   << DeclName << MemExprE->getSourceRange()),
-          *this, OCD_AllCandidates, Args);
+          *this, OCD_AmbiguousCandidates, Args);
       // FIXME: Leaking incoming expressions!
       return ExprError();
 
@@ -13717,7 +13748,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
                             PDiag(diag::err_ovl_ambiguous_object_call)
                                 << Object.get()->getType()
                                 << Object.get()->getSourceRange()),
-        *this, OCD_ViableCandidates, Args);
+        *this, OCD_AmbiguousCandidates, Args);
     break;
 
   case OR_Deleted:
@@ -13952,7 +13983,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc,
         PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_ambiguous_oper_unary)
                                        << "->" << Base->getType()
                                        << Base->getSourceRange()),
-        *this, OCD_ViableCandidates, Base);
+        *this, OCD_AmbiguousCandidates, Base);
     return ExprError();
 
   case OR_Deleted:
@@ -14032,7 +14063,7 @@ ExprResult Sema::BuildLiteralOperatorCall(LookupResult &R,
     CandidateSet.NoteCandidates(
         PartialDiagnosticAt(R.getNameLoc(), PDiag(diag::err_ovl_ambiguous_call)
                                                 << R.getLookupName()),
-        *this, OCD_ViableCandidates, Args);
+        *this, OCD_AmbiguousCandidates, Args);
     return ExprError();
   }
 

diff  --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp
index 0c58da01be59..d64807ed5abd 100644
--- a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p15.cpp
@@ -8,7 +8,7 @@ struct B2 {
   B2(int); // expected-note {{candidate}}
 };
 
-struct D1 : B1, B2 { // expected-note 2{{candidate}}
+struct D1 : B1, B2 {
   using B1::B1; // expected-note {{inherited here}}
   using B2::B2; // expected-note {{inherited here}}
 };
@@ -35,11 +35,11 @@ namespace default_ctor {
     operator D&&();
   };
 
-  struct A { // expected-note 2{{candidate}}
+  struct A {
     A(); // expected-note {{candidate}}
 
-    A(C &&); // expected-note {{candidate}}
-    C &operator=(C&&); // expected-note {{candidate}}
+    A(C &&);
+    C &operator=(C&&);
 
     A(D &&);
     D &operator=(D&&); // expected-note {{candidate}}
@@ -47,11 +47,11 @@ namespace default_ctor {
     A(convert_to_D2); // expected-note {{candidate}}
   };
 
-  struct B { // expected-note 2{{candidate}}
+  struct B {
     B(); // expected-note {{candidate}}
 
-    B(C &&); // expected-note {{candidate}}
-    C &operator=(C&&); // expected-note {{candidate}}
+    B(C &&);
+    C &operator=(C&&);
 
     B(D &&);
     D &operator=(D&&); // expected-note {{candidate}}
@@ -66,14 +66,14 @@ namespace default_ctor {
     using B::operator=;
   };
   struct D : A, B {
-    using A::A; // expected-note 3{{inherited here}}
+    using A::A; // expected-note 2{{inherited here}}
     using A::operator=;
-    using B::B; // expected-note 3{{inherited here}}
+    using B::B; // expected-note 2{{inherited here}}
     using B::operator=;
 
     D(int);
-    D(const D&); // expected-note {{candidate}}
-    D &operator=(const D&); // expected-note {{candidate}}
+    D(const D&);
+    D &operator=(const D&);
   };
 
   C c;

diff  --git a/clang/test/CXX/drs/dr15xx.cpp b/clang/test/CXX/drs/dr15xx.cpp
index bd714865eef8..80a27e7863c9 100644
--- a/clang/test/CXX/drs/dr15xx.cpp
+++ b/clang/test/CXX/drs/dr15xx.cpp
@@ -399,23 +399,20 @@ namespace dr1589 {   // dr1589: 3.7 c++11
   void g2() { f2({"foo","bar"}); }              // chooses #4
 
   namespace with_error {
-    void f0(long);                        // #0    expected-note {{candidate function}}
-    void f0(std::initializer_list<int>);  // #00   expected-note {{candidate function}}
-    void f0(std::initializer_list<int>, int = 0);  // Makes selection of #00 ambiguous \
-    // expected-note {{candidate function}}
-    void g0() { f0({1L}); }                 // chooses #00    expected-error{{call to 'f0' is ambiguous}}
-
-    void f1(int);                           // #1   expected-note {{candidate function}}
-    void f1(std::initializer_list<long>);   // #2   expected-note {{candidate function}}
-    void f1(std::initializer_list<long>, int = 0);   // Makes selection of #00 ambiguous \
-    // expected-note {{candidate function}}
-    void g1() { f1({42}); }                 // chooses #2   expected-error{{call to 'f1' is ambiguous}}
-
-    void f2(std::pair<const char*, const char*>); // #3   TODO: expected- note {{candidate function}}
-    void f2(std::initializer_list<std::string>);  // #4   expected-note {{candidate function}}
-    void f2(std::initializer_list<std::string>, int = 0);   // Makes selection of #00 ambiguous \
-    // expected-note {{candidate function}}
-    void g2() { f2({"foo","bar"}); }        // chooses #4   expected-error{{call to 'f2' is ambiguous}}
+    void f0(long);                        // #0
+    void f0(std::initializer_list<int>);  // #00     expected-note {{candidate function}}
+    void f0(std::initializer_list<int>, int = 0); // expected-note {{candidate function}}
+    void g0() { f0({1L}); }                 // expected-error{{call to 'f0' is ambiguous}}
+
+    void f1(int);                           // #1
+    void f1(std::initializer_list<long>);   // #2     expected-note {{candidate function}}
+    void f1(std::initializer_list<long>, int = 0); // expected-note {{candidate function}}
+    void g1() { f1({42}); }                 // expected-error{{call to 'f1' is ambiguous}}
+
+    void f2(std::pair<const char*, const char*>); // #3
+    void f2(std::initializer_list<std::string>);  // #4      expected-note {{candidate function}}
+    void f2(std::initializer_list<std::string>, int = 0); // expected-note {{candidate function}}
+    void g2() { f2({"foo","bar"}); }        // expected-error{{call to 'f2' is ambiguous}}
   }
 
 } // dr1589

diff  --git a/clang/test/CXX/drs/dr16xx.cpp b/clang/test/CXX/drs/dr16xx.cpp
index 44d5b8f3f5b6..3bbb19763648 100644
--- a/clang/test/CXX/drs/dr16xx.cpp
+++ b/clang/test/CXX/drs/dr16xx.cpp
@@ -111,13 +111,13 @@ namespace dr1638 { // dr1638: yes
 namespace dr1645 { // dr1645: 3.9
 #if __cplusplus >= 201103L
   struct A {
-    constexpr A(int, float = 0); // expected-note 2{{candidate}}
+    constexpr A(int, float = 0); // expected-note {{candidate}}
     explicit A(int, int = 0); // expected-note 2{{candidate}}
     A(int, int, int = 0) = delete; // expected-note {{candidate}}
   };
 
-  struct B : A { // expected-note 2{{candidate}}
-    using A::A; // expected-note 5{{inherited here}}
+  struct B : A {
+    using A::A; // expected-note 4{{inherited here}}
   };
 
   constexpr B a(0); // expected-error {{ambiguous}}

diff  --git a/clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p3.cpp b/clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p3.cpp
index 4ed1d30b83d5..2f895981b9b6 100644
--- a/clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p3.cpp
+++ b/clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p3.cpp
@@ -2,7 +2,7 @@
 
 namespace std_example {
   template <class T> struct A {
-    explicit A(const T &, ...) noexcept; // expected-note {{explicit}} expected-note 2{{candidate}}
+    explicit A(const T &, ...) noexcept; // expected-note {{explicit}}
     A(T &&, ...); // expected-note 2{{candidate}}
   };
 

diff  --git a/clang/test/CXX/special/class.inhctor/p1.cpp b/clang/test/CXX/special/class.inhctor/p1.cpp
index 842b725cb0b3..389f365b7428 100644
--- a/clang/test/CXX/special/class.inhctor/p1.cpp
+++ b/clang/test/CXX/special/class.inhctor/p1.cpp
@@ -3,19 +3,19 @@
 // Note: [class.inhctor] was removed by P0136R1. This tests the new behavior
 // for the wording that used to be there.
 
-struct A { // expected-note 4{{candidate constructor (the implicit}}
-  A(...); // expected-note 4{{candidate constructor}} expected-note 4{{candidate inherited constructor}}
+struct A {
+  A(...); // expected-note {{candidate constructor}} expected-note {{candidate inherited constructor}}
   A(int = 0, int = 0, int = 0, int = 0, ...); // expected-note 3{{candidate constructor}} expected-note 3{{candidate inherited constructor}}
   A(int = 0, int = 0, ...); // expected-note 3{{candidate constructor}} expected-note 3{{candidate inherited constructor}}
 
-  template<typename T> A(T, int = 0, ...); // expected-note 3{{candidate constructor}} expected-note 3{{candidate inherited constructor}}
+  template<typename T> A(T, int = 0, ...);
 
   template<typename T, int N> A(const T (&)[N]); // expected-note {{candidate constructor}} expected-note {{candidate inherited constructor}}
   template<typename T, int N> A(const T (&)[N], int = 0); // expected-note {{candidate constructor}} expected-note {{candidate inherited constructor}}
 };
 
-struct B : A { // expected-note 4{{candidate constructor (the implicit}}
-  using A::A; // expected-note 15{{inherited here}}
+struct B : A {
+  using A::A; // expected-note 9{{inherited here}}
   B(void*);
 };
 

diff  --git a/clang/test/CXX/special/class.inhctor/p4.cpp b/clang/test/CXX/special/class.inhctor/p4.cpp
index 69fbea3e0eb0..a5d2cd74b50f 100644
--- a/clang/test/CXX/special/class.inhctor/p4.cpp
+++ b/clang/test/CXX/special/class.inhctor/p4.cpp
@@ -60,13 +60,13 @@ H h2("foo"); // expected-error {{call to deleted constructor of 'H'}}
 // same signature.
 namespace DRnnnn {
   struct A {
-    constexpr A(int, float = 0) {} // expected-note {{candidate}}
+    constexpr A(int, float = 0) {}
     explicit A(int, int = 0) {} // expected-note {{candidate}}
 
     A(int, int, int = 0) = delete; // expected-note {{deleted}}
   };
   struct B : A {
-    using A::A; // expected-note 3{{inherited here}}
+    using A::A; // expected-note 2{{inherited here}}
   };
 
   constexpr B b0(0, 0.0f); // ok, constexpr

diff  --git a/clang/test/CXX/special/class.inhctor/p7.cpp b/clang/test/CXX/special/class.inhctor/p7.cpp
index 2d7acdcc2ce2..4bbc2fc098a4 100644
--- a/clang/test/CXX/special/class.inhctor/p7.cpp
+++ b/clang/test/CXX/special/class.inhctor/p7.cpp
@@ -9,7 +9,7 @@ struct B1 {
 struct B2 {
   B2(int); // expected-note {{candidate}}
 };
-struct D1 : B1, B2 { // expected-note 2{{candidate}}
+struct D1 : B1, B2 {
   using B1::B1; // expected-note {{inherited here}}
   using B2::B2; // expected-note {{inherited here}}
 };

diff  --git a/clang/test/SemaCXX/ambig-user-defined-conversions.cpp b/clang/test/SemaCXX/ambig-user-defined-conversions.cpp
index 276c1b07b5d9..8d8fa4fef6d9 100644
--- a/clang/test/SemaCXX/ambig-user-defined-conversions.cpp
+++ b/clang/test/SemaCXX/ambig-user-defined-conversions.cpp
@@ -13,7 +13,7 @@ namespace test0 {
   extern B f(); 
   B b1;
 
-  void func(const int ci, const char cc); // expected-note {{candidate function}}
+  void func(const int ci, const char cc);
   void func(const char ci, const B b); // expected-note {{candidate function}}
   void func(const B b, const int ci); // expected-note {{candidate function}}
 

diff  --git a/clang/test/SemaCXX/builtin-ptrtomember-ambig.cpp b/clang/test/SemaCXX/builtin-ptrtomember-ambig.cpp
index 61e347879a75..4330c0cc48aa 100644
--- a/clang/test/SemaCXX/builtin-ptrtomember-ambig.cpp
+++ b/clang/test/SemaCXX/builtin-ptrtomember-ambig.cpp
@@ -17,11 +17,8 @@ struct C : B {
 
 
 void foo(C c, int A::* pmf) {
-       				// FIXME. Why so many built-in candidates?
 	int i = c->*pmf; 	// expected-error {{use of overloaded operator '->*' is ambiguous}} \
-				// expected-note {{built-in candidate operator->*(const struct A *, const int struct A::*)}} \
 				// expected-note {{built-in candidate operator->*(const struct A *, int struct A::*)}} \
-				// expected-note {{built-in candidate operator->*(struct A *, const int struct A::*)}} \
 				// expected-note {{built-in candidate operator->*(struct A *, int struct A::*)}}
 }
 

diff  --git a/clang/test/SemaCXX/builtin-ptrtomember-overload-1.cpp b/clang/test/SemaCXX/builtin-ptrtomember-overload-1.cpp
index 2d93c6b2dff3..a717c283ab78 100644
--- a/clang/test/SemaCXX/builtin-ptrtomember-overload-1.cpp
+++ b/clang/test/SemaCXX/builtin-ptrtomember-overload-1.cpp
@@ -42,5 +42,5 @@ void foo1(C1 c1, int A::* pmf) {
 void foo1(C1 c1, int E::* pmf) {
         int i = c1->*pmf;	// expected-error {{use of overloaded operator '->*' is ambiguous}} \
                                 // expected-note {{because of ambiguity in conversion of 'C1' to 'E *'}} \
-                                // expected-note 4 {{built-in candidate operator}}
+                                // expected-note 2 {{built-in candidate operator}}
 }

diff  --git a/clang/test/SemaCXX/copy-initialization.cpp b/clang/test/SemaCXX/copy-initialization.cpp
index cd7e5f07e140..8866fe70db86 100644
--- a/clang/test/SemaCXX/copy-initialization.cpp
+++ b/clang/test/SemaCXX/copy-initialization.cpp
@@ -4,7 +4,7 @@
 
 class X {
 public:
-  explicit X(const X&); // expected-note {{candidate constructor}}
+  explicit X(const X&);
   X(int*); // expected-note 3{{candidate constructor}}
   explicit X(float*); // expected-note {{candidate constructor}}
 };

diff  --git a/clang/test/SemaCXX/cxx0x-initializer-constructor.cpp b/clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
index 870bbe5ce36e..513c670d392d 100644
--- a/clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
+++ b/clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
@@ -266,7 +266,7 @@ namespace PR12120 {
   struct A { explicit A(int); A(float); }; // expected-note {{declared here}}
   A a = { 0 }; // expected-error {{constructor is explicit}}
 
-  struct B { explicit B(short); B(long); }; // expected-note 4{{candidate}}
+  struct B { explicit B(short); B(long); }; // expected-note 2{{candidate}}
   B b = { 0 }; // expected-error {{ambiguous}}
 
   struct C { explicit C(short); C(long); }; // expected-note 2{{candidate}}

diff  --git a/clang/test/SemaCXX/microsoft-vs-float128.cpp b/clang/test/SemaCXX/microsoft-vs-float128.cpp
index d271e470032d..77d249881290 100644
--- a/clang/test/SemaCXX/microsoft-vs-float128.cpp
+++ b/clang/test/SemaCXX/microsoft-vs-float128.cpp
@@ -11,7 +11,7 @@ template <typename T> struct is_same<T, T> { static constexpr bool value = true;
 
 
 struct S {
-  // The only numeric types S can be converted to is __int128 and __float128.
+  // The only numeric types S can be converted to are [unsigned] __int128 and __float128.
   template <typename T, typename = typename enable_if<
                             !((__is_integral(T) && sizeof(T) != 16) ||
                               is_same<T, float>::value ||
@@ -29,6 +29,8 @@ void f() {
   double d = S() + 1.0;
 #ifndef MS
   // expected-error at -2{{use of overloaded operator '+' is ambiguous}}
-  // expected-note at -3 36{{built-in candidate operator+}}
+  // expected-note at -3 {{built-in candidate operator+(__float128, double)}}
+  // expected-note at -4 {{built-in candidate operator+(__int128, double)}}
+  // expected-note at -5 {{built-in candidate operator+(unsigned __int128, double)}}
 #endif
 }

diff  --git a/clang/test/SemaCXX/overload-call.cpp b/clang/test/SemaCXX/overload-call.cpp
index befa927f0677..a34bce5014ab 100644
--- a/clang/test/SemaCXX/overload-call.cpp
+++ b/clang/test/SemaCXX/overload-call.cpp
@@ -12,9 +12,9 @@ void test_f(int iv, float fv) {
 }
 
 int* g(int, float, int); // expected-note {{candidate function}}
-float* g(int, int, int); // expected-note {{candidate function}}
+float* g(int, int, int);
 double* g(int, float, float); // expected-note {{candidate function}}
-char* g(int, float, ...); // expected-note {{candidate function}}
+char* g(int, float, ...);
 void g();
 
 void test_g(int iv, float fv) {

diff  --git a/clang/test/SemaCXX/overload-member-call.cpp b/clang/test/SemaCXX/overload-member-call.cpp
index 2d017a499ad9..41f3946de0bf 100644
--- a/clang/test/SemaCXX/overload-member-call.cpp
+++ b/clang/test/SemaCXX/overload-member-call.cpp
@@ -14,7 +14,7 @@ struct X {
 
   int& g(int) const; // expected-note 2 {{candidate function}}
   float& g(int); // expected-note 2 {{candidate function}}
-  static double& g(double); // expected-note 2 {{candidate function}}
+  static double& g(double);
 
   void h(int);
 

diff  --git a/clang/test/SemaCXX/overloaded-builtin-operators.cpp b/clang/test/SemaCXX/overloaded-builtin-operators.cpp
index 4fa376aed036..d237dfe6c091 100644
--- a/clang/test/SemaCXX/overloaded-builtin-operators.cpp
+++ b/clang/test/SemaCXX/overloaded-builtin-operators.cpp
@@ -194,10 +194,9 @@ struct A {
 };
 
 void test_dr425(A a) {
-  // FIXME: lots of candidates here!
   (void)(1.0f * a); // expected-error{{ambiguous}} \
                     // expected-note 4{{candidate}} \
-                    // expected-note {{remaining 140 candidates omitted; pass -fshow-overloads=all to show them}}
+                    // expected-note {{remaining 8 candidates omitted; pass -fshow-overloads=all to show them}}
 }
 
 // pr5432
@@ -237,9 +236,10 @@ namespace PR8477 {
     (void)(foo - zero);
     (void)(zero + foo);
     (void)(zero[foo]);
+    // FIXME: It would be nice to report fewer candidates here.
     (void)(foo - foo); // expected-error{{use of overloaded operator '-' is ambiguous}} \
     // expected-note 4{{built-in candidate operator-}} \
-    // expected-note{{candidates omitted}}
+    // expected-note{{142 candidates omitted}}
     return foo[zero] == zero;
   }
 }

diff  --git a/clang/test/SemaTemplate/cxx1z-using-declaration.cpp b/clang/test/SemaTemplate/cxx1z-using-declaration.cpp
index 87ca748f8fd5..ba5918ce0989 100644
--- a/clang/test/SemaTemplate/cxx1z-using-declaration.cpp
+++ b/clang/test/SemaTemplate/cxx1z-using-declaration.cpp
@@ -16,7 +16,7 @@ void test_Unexpanded() {
 }
 
 // Test using non-type members from pack of base classes.
-template<typename ...T> struct A : T... { // expected-note 2{{candidate}}
+template<typename ...T> struct A : T... {
   using T::T ...; // expected-note 2{{inherited here}}
   using T::operator() ...;
   using T::operator T* ...;
@@ -41,7 +41,7 @@ namespace test_A {
     Y(int, int);
     void operator()(int, int);
     operator Y *();
-    void h(int, int); // expected-note {{not viable}}
+    void h(int, int);
   };
   struct Z {
     Z();
@@ -177,14 +177,14 @@ namespace test_lambda1 {
   };
   struct B {
     template<typename> struct X {
-      void f(int, int); // expected-note {{declared here}} expected-note {{not viable}}
+      void f(int, int); // expected-note {{declared here}}
       using type = int;
     };
   };
   struct C {
     template<typename> struct X {
       void f(int); // expected-note {{candidate}}
-      void f(int, int); // expected-note {{not viable}}
+      void f(int, int);
       using type = int;
     };
   };

diff  --git a/clang/test/SemaTemplate/instantiate-expr-3.cpp b/clang/test/SemaTemplate/instantiate-expr-3.cpp
index 90c322cbf373..142e4ebcedc6 100644
--- a/clang/test/SemaTemplate/instantiate-expr-3.cpp
+++ b/clang/test/SemaTemplate/instantiate-expr-3.cpp
@@ -23,7 +23,7 @@ namespace N1 {
 }
 
 namespace N2 {
-  long& operator+=(N1::X&, long); // expected-note{{candidate}}
+  long& operator+=(N1::X&, long);
 
   template<typename T, typename U, typename Result>
   struct PlusEquals0 {

diff  --git a/clang/test/SemaTemplate/temp_arg_nontype.cpp b/clang/test/SemaTemplate/temp_arg_nontype.cpp
index 330a954e0ddd..08ed7d5004ad 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype.cpp
@@ -445,10 +445,10 @@ namespace nondependent_default_arg_ordering {
   template<typename A> void f(X<A>); // expected-note {{candidate}}
   template<typename A> void f(X<A, &m>); // expected-note {{candidate}}
   template<typename A, A B> void f(X<A, B>); // expected-note 2{{candidate}}
-  template<template<typename U, U> class T, typename A, int *B> void f(T<A, B>); // expected-note 2{{candidate}}
+  template<template<typename U, U> class T, typename A, int *B> void f(T<A, B>);
   void g() {
     // FIXME: The first and second function templates above should be
-    // considered more specialized than the last two, but during partial
+    // considered more specialized than the third, but during partial
     // ordering we fail to check that we actually deduced template arguments
     // that make the deduced A identical to A.
     X<int *, &n> x; f(x); // expected-error {{ambiguous}}


        


More information about the cfe-commits mailing list