]> granicus.if.org Git - clang/commitdiff
Improve the reporting of non-viable overload candidates by noting the reason
authorJohn McCall <rjmccall@apple.com>
Wed, 13 Jan 2010 00:25:19 +0000 (00:25 +0000)
committerJohn McCall <rjmccall@apple.com>
Wed, 13 Jan 2010 00:25:19 +0000 (00:25 +0000)
why the candidate is non-viable.  There's a lot we can do to improve this, but
it's a good start.  Further improvements should probably be integrated with the
bad-initialization reporting routines.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93277 91177308-0d34-0410-b5e6-96231b3b80d8

23 files changed:
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaOverload.cpp
test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp
test/CXX/temp/temp.decls/temp.class/temp.static/p1-inst.cpp
test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp
test/CXX/temp/temp.param/p3.cpp
test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp
test/CXX/temp/temp.spec/temp.explicit/p1.cpp
test/SemaCXX/condition.cpp
test/SemaCXX/constructor-initializer.cpp
test/SemaCXX/converting-constructor.cpp
test/SemaCXX/dcl_init_aggr.cpp
test/SemaCXX/direct-initializer.cpp
test/SemaCXX/functional-cast.cpp
test/SemaCXX/namespace.cpp
test/SemaCXX/nested-name-spec.cpp
test/SemaCXX/overload-call.cpp
test/SemaCXX/overloaded-builtin-operators.cpp
test/SemaTemplate/ambiguous-ovl-print.cpp
test/SemaTemplate/default-expr-arguments.cpp
test/SemaTemplate/explicit-instantiation.cpp
test/SemaTemplate/fun-template-def.cpp
test/SemaTemplate/instantiate-expr-4.cpp

index 8fcc97b42ccbb47da1145fcc5164a4f063a69457..95747a875ba7468d4c287ce210491aa84ce159e5 100644 (file)
@@ -899,19 +899,29 @@ def err_ovl_deleted_member_call : Error<
   "call to %select{unavailable|deleted}0 member function %1">;
 def note_ovl_candidate : Note<"candidate "
     "%select{function|function|constructor|"
+    "function |function |constructor |"
     "is the implicit default constructor|"
     "is the implicit copy constructor|"
-    "is the implicit copy assignment operator}0">;
-def note_ovl_template_candidate : Note<
-  "candidate function template specialization %0">;
+    "is the implicit copy assignment operator}0%1">;
+// Note that we don't treat templates differently for this diagnostic.
+def note_ovl_candidate_arity : Note<"candidate "
+    "%select{function|function|constructor|function|function|constructor|"
+    "constructor (the implicit default constructor)|"
+    "constructor (the implicit copy constructor)|"
+    "function (the implicit copy assignment operator)}0 not viable: requires"
+    "%select{ at least| at most|}2 %3 argument%s3, but %4 %plural{1:was|:were}4 "
+    "provided">;
 def note_ovl_candidate_deleted : Note<
-  "candidate %select{function|function|constructor}0 has been explicitly "
-  "%select{made unavailable|deleted}1">;
-def note_ovl_template_candidate_deleted : Note<
-  "candidate function template specialization %0 has been explicit "
-  "&select{made unavailable|deleted}1">;
-def note_ovl_candidate_not_viable : Note<"function not viable because"
-                          " of ambiguity in conversion of argument %0">;
+  "candidate %select{function|function|constructor|"
+  "function |function |constructor |||}0%1 "
+  "has been explicitly %select{made unavailable|deleted}2">;
+def note_ovl_candidate_bad_conv : Note<"candidate "
+    "%select{function|function|constructor|"
+    "function |function |constructor |"
+    "constructor (the implicit default constructor)|"
+    "constructor (the implicit copy constructor)|"
+    "function (the implicit copy assignment operator)}0%1"
+    " not viable: no known conversion from %2 to %3 for argument %4">;
 def note_ambiguous_type_conversion: Note<
     "because of ambiguity in conversion of %0 to %1">;
 def note_ovl_builtin_binary_candidate : Note<
index a357e425549b7373977e23ba636489846290f90e..4f299ff5b0ed503b18c716b421cb3cdd884dd745 100644 (file)
@@ -4269,19 +4269,28 @@ enum OverloadCandidateKind {
   oc_function,
   oc_method,
   oc_constructor,
+  oc_function_template,
+  oc_method_template,
+  oc_constructor_template,
   oc_implicit_default_constructor,
   oc_implicit_copy_constructor,
-  oc_implicit_copy_assignment,
-  oc_template_specialization // function, constructor, or conversion template
+  oc_implicit_copy_assignment
 };
 
-OverloadCandidateKind ClassifyOverloadCandidate(FunctionDecl *Fn) {
-  if (Fn->getPrimaryTemplate())
-    return oc_template_specialization;
+OverloadCandidateKind ClassifyOverloadCandidate(Sema &S,
+                                                FunctionDecl *Fn,
+                                                std::string &Description) {
+  bool isTemplate = false;
+
+  if (FunctionTemplateDecl *FunTmpl = Fn->getPrimaryTemplate()) {
+    isTemplate = true;
+    Description = S.getTemplateArgumentBindingsText(
+      FunTmpl->getTemplateParameters(), *Fn->getTemplateSpecializationArgs());
+  }
 
   if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(Fn)) {
     if (!Ctor->isImplicit())
-      return oc_constructor;
+      return isTemplate ? oc_constructor_template : oc_constructor;
 
     return Ctor->isCopyConstructor() ? oc_implicit_copy_constructor
                                      : oc_implicit_default_constructor;
@@ -4291,34 +4300,24 @@ OverloadCandidateKind ClassifyOverloadCandidate(FunctionDecl *Fn) {
     // This actually gets spelled 'candidate function' for now, but
     // it doesn't hurt to split it out.
     if (!Meth->isImplicit())
-      return oc_method;
+      return isTemplate ? oc_method_template : oc_method;
 
     assert(Meth->isCopyAssignment()
            && "implicit method is not copy assignment operator?");
     return oc_implicit_copy_assignment;
   }
 
-  return oc_function;
-}
-
-std::string DescribeFunctionTemplate(Sema &S, FunctionDecl *Fn) {
-  FunctionTemplateDecl *FunTmpl = Fn->getPrimaryTemplate();
-  return S.getTemplateArgumentBindingsText(FunTmpl->getTemplateParameters(),
-                                       *Fn->getTemplateSpecializationArgs());
+  return isTemplate ? oc_function_template : oc_function;
 }
 
 } // end anonymous namespace
 
 // Notes the location of an overload candidate.
 void Sema::NoteOverloadCandidate(FunctionDecl *Fn) {
-  OverloadCandidateKind K = ClassifyOverloadCandidate(Fn);
-  if (K == oc_template_specialization) {
-    Diag(Fn->getLocation(), diag::note_ovl_template_candidate)
-      << DescribeFunctionTemplate(*this, Fn);
-    return;
-  }
-
-  Diag(Fn->getLocation(), diag::note_ovl_candidate) << (unsigned) K;
+  std::string FnDesc;
+  OverloadCandidateKind K = ClassifyOverloadCandidate(*this, Fn, FnDesc);
+  Diag(Fn->getLocation(), diag::note_ovl_candidate)
+    << (unsigned) K << FnDesc;
 }
 
 /// Diagnoses an ambiguous conversion.  The partial diagnostic is the
@@ -4337,41 +4336,104 @@ void Sema::DiagnoseAmbiguousConversion(const ImplicitConversionSequence &ICS,
 
 namespace {
 
-void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand) {
+void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, unsigned I,
+                           Expr **Args, unsigned NumArgs) {
+  assert(Cand->Function && "for now, candidate must be a function");
+  FunctionDecl *Fn = Cand->Function;
+
+  // There's a conversion slot for the object argument if this is a
+  // non-constructor method.  Note that 'I' corresponds the
+  // conversion-slot index.
+  if (isa<CXXMethodDecl>(Fn) && !isa<CXXConstructorDecl>(Fn)) {
+    // FIXME: talk usefully about bad conversions for object arguments.
+    if (I == 0) return S.NoteOverloadCandidate(Fn);
+    else I--;
+  }
+
+  // FIXME: can we have a bad conversion on an ellipsis parameter?
+  assert(I < NumArgs && "index exceeds number of formal arguments");
+  assert(I < Fn->getType()->getAs<FunctionProtoType>()->getNumArgs() &&
+         "index exceeds number of formal parameters");
+
+  std::string FnDesc;
+  OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, FnDesc);
+
+  QualType FromTy = Args[I]->getType();
+  QualType ToTy = Fn->getType()->getAs<FunctionProtoType>()->getArgType(I);
+
+  // TODO: specialize based on the kind of mismatch
+  S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv)
+    << (unsigned) FnKind << FnDesc
+    << Args[I]->getSourceRange() << FromTy << ToTy
+    << I+1;
+}
+
+void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand,
+                           Expr **Args, unsigned NumArgs) {
   FunctionDecl *Fn = Cand->Function;
 
   // Note deleted candidates, but only if they're viable.
   if (Cand->Viable && (Fn->isDeleted() || Fn->hasAttr<UnavailableAttr>())) {
-    OverloadCandidateKind FnKind = ClassifyOverloadCandidate(Fn);
-
-    if (FnKind == oc_template_specialization) {
-      S.Diag(Fn->getLocation(), diag::note_ovl_template_candidate_deleted)
-        << DescribeFunctionTemplate(S, Fn) << Fn->isDeleted();
-      return;
-    }
+    std::string FnDesc;
+    OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, FnDesc);
 
     S.Diag(Fn->getLocation(), diag::note_ovl_candidate_deleted)
-      << FnKind << Fn->isDeleted();
+      << FnKind << FnDesc << Fn->isDeleted();
+    return;
+  }
+
+  // We don't really have anything else to say about viable candidates.
+  if (Cand->Viable) {
+    S.NoteOverloadCandidate(Fn);
     return;
   }
 
-  bool errReported = false;
-  if (!Cand->Viable && Cand->Conversions.size() > 0) {
-    for (int i = Cand->Conversions.size()-1; i >= 0; i--) {
-      const ImplicitConversionSequence &Conversion = 
-        Cand->Conversions[i];
+  // Diagnose arity mismatches.
+  // TODO: treat calls to a missing default constructor as a special case
+  unsigned NumFormalArgs = NumArgs;
+  if (isa<CXXMethodDecl>(Fn) && !isa<CXXConstructorDecl>(Fn))
+    NumFormalArgs--;
+  const FunctionProtoType *FnTy = Fn->getType()->getAs<FunctionProtoType>();
+  unsigned MinParams = Fn->getMinRequiredArguments();
+  if (NumFormalArgs < MinParams ||
+      (NumFormalArgs > FnTy->getNumArgs() && !FnTy->isVariadic())) {
+    std::string Description;
+    OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, Description);
+
+    // at least / at most / exactly
+    unsigned mode, modeCount;
+    if (NumFormalArgs < MinParams) {
+      if (MinParams != FnTy->getNumArgs())
+        mode = 0; // "at least"
+      else
+        mode = 2; // "exactly"
+      modeCount = MinParams;
+    } else {
+      if (MinParams != FnTy->getNumArgs())
+        mode = 1; // "at most"
+      else
+        mode = 2; // "exactly"
+      modeCount = FnTy->getNumArgs();
+    }
+
+    S.Diag(Fn->getLocation(), diag::note_ovl_candidate_arity)
+      << (unsigned) FnKind << Description << mode << modeCount << NumFormalArgs;
+    return;
+  }
 
-      if (!Conversion.isAmbiguous())
+  // Look for bad conversions.
+  if (!Cand->Conversions.empty()) {
+    for (unsigned I = 0, N = Cand->Conversions.size(); I != N; ++I) {
+      if (!Cand->Conversions[I].isBad())
         continue;
 
-      S.DiagnoseAmbiguousConversion(Conversion, Fn->getLocation(),
-                         PDiag(diag::note_ovl_candidate_not_viable) << (i+1));
-      errReported = true;
+      DiagnoseBadConversion(S, Cand, I, Args, NumArgs);
+      return;
     }
   }
 
-  if (!errReported)
-    S.NoteOverloadCandidate(Fn);
+  // Give up and give the generic message.
+  S.NoteOverloadCandidate(Fn);
 }
 
 void NoteSurrogateCandidate(Sema &S, OverloadCandidate *Cand) {
@@ -4506,7 +4568,7 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
     OverloadCandidate *Cand = *I;
 
     if (Cand->Function)
-      NoteFunctionCandidate(*this, Cand);
+      NoteFunctionCandidate(*this, Cand, Args, NumArgs);
     else if (Cand->IsSurrogate)
       NoteSurrogateCandidate(*this, Cand);
 
@@ -4714,7 +4776,8 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
                            PDiag(),
                            PDiag(diag::err_addr_ovl_ambiguous)
                                << TemplateMatches[0]->getDeclName(),
-                           PDiag(diag::note_ovl_template_candidate));
+                           PDiag(diag::note_ovl_candidate)
+                               << (unsigned) oc_function_template);
     MarkDeclarationReferenced(From->getLocStart(), Result);
     return Result;
   }
index 34ce54665613b45743eecc95fb2394166309f6ff..cf3db5175fa4312d754d1b5b83b5c97b9386deea 100644 (file)
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
 struct Base { }; // expected-note{{candidate is the implicit copy constructor}}
-struct Derived : Base { }; // expected-note{{candidate is the implicit copy constructor}}
+struct Derived : Base { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable}}
 struct Unrelated { };
 struct Derived2 : Base { };
 struct Diamond : Derived, Derived2 { };
index 6f23e78c1cc220f581159e68326190ba00b7b0a2..9fc4a5809f357193fbbe6b53c7864626b3572d1b 100644 (file)
@@ -14,7 +14,7 @@ struct InitOkay {
   InitOkay(int) { }
 };
 
-struct CannotInit { }; // expected-note{{candidate is the implicit copy constructor}}
+struct CannotInit { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable}}
 
 int &returnInt() { return X<int>::value; }
 float &returnFloat() { return X<float>::value; }
index e281150241b372f3f2168682356d937a4d483d67..2eae1125c0dbd7bae3d6cb04d911047b953dd4b1 100644 (file)
@@ -12,7 +12,7 @@ struct X1 {
   X1(int);
 };
 
-struct X2 { }; // expected-note{{candidate is the implicit copy constructor}}
+struct X2 { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable}}
 
 int& get_int() { return X0<int>::value; }
 X1& get_X1() { return X0<X1>::value; }
index a48702d662893cded81945ded1070ad286a559f2..8fcc2dc85957928edccc8017e2fd2c7fc79aa2eb 100644 (file)
@@ -15,7 +15,7 @@ template<template<class T> class Y> struct X1 {
 // could be interpreted as either a non-type template-parameter or a
 // type-parameter (because its identifier is the name of an already
 // existing class) is taken as a type-parameter. For example, 
-class T { /* ... */ };  // expected-note{{candidate is the implicit copy constructor}}
+class T { /* ... */ };  // expected-note{{candidate constructor (the implicit copy constructor) not viable}}
 int i; 
 
 template<class T, T i> struct X2 {
index 29045cc86015fdeef4da8ae1e2e62582a6380c5f..772aef6b585a4ae4b8e10465ffda3a733a23bb77 100644 (file)
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
-struct IntHolder { // expected-note{{here}} // expected-note 2{{candidate is the implicit copy constructor}}
+struct IntHolder { // expected-note{{here}} // expected-note 2{{candidate constructor (the implicit copy constructor)}}
   IntHolder(int); // expected-note 2{{candidate constructor}}
 };
 
index eb729ff676d09fef31ae6109ddad3d49203d4a80..b42633924e828a7a431d099628e70ed4d4449d2c 100644 (file)
@@ -48,7 +48,7 @@ template void X1<int>::f<>(int&, int*); // expected-note{{instantiation}}
 
 // Explicitly instantiate members of a class template
 struct Incomplete; // expected-note{{forward declaration}}
-struct NonDefaultConstructible { // expected-note{{candidate is the implicit copy constructor}}
+struct NonDefaultConstructible { // expected-note{{candidate constructor (the implicit copy constructor) not viable}}
   NonDefaultConstructible(int); // expected-note{{candidate constructor}}
 };
 
index 7931d11d14de962f39f366c2b81ab464d1a102c0..fe802d0555ed4aef54767dc64fa395a27a3d48bc 100644 (file)
@@ -16,8 +16,8 @@ void test() {
   for (;s;) ; // expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}}
   switch (s) {} // expected-error {{statement requires expression of integer type ('struct S' invalid)}}
 
-  while (struct S {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}} expected-note{{candidate is the implicit copy constructor}}
-  while (struct {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{value of type 'struct <anonymous>' is not contextually convertible to 'bool'}} expected-note{{candidate is the implicit copy constructor}}
+  while (struct S {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}} expected-note{{candidate constructor (the implicit copy constructor)}}
+  while (struct {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{value of type 'struct <anonymous>' is not contextually convertible to 'bool'}} expected-note{{candidate constructor (the implicit copy constructor)}}
   switch (enum {E} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{cannot initialize}}
 
   if (int x=0) { // expected-note 2 {{previous definition is here}}
index ecab4e47fda45d5a4499e93bab92f3ab7b3cb29d..53f057ed0f35f4218ae8c4c92beed99ea1d3ab58 100644 (file)
@@ -97,7 +97,7 @@ struct Current : Derived {
                                                   // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
 };
 
-struct M {              // expected-note 2 {{candidate is the implicit copy constructor}} \
+struct M {              // expected-note 2 {{candidate constructor (the implicit copy constructor)}} \
                         // expected-note {{declared here}} \
                         // expected-note {{declared here}}
   M(int i, int j);      // expected-note 2 {{candidate constructor}}
index 3ef003ce76c8ad857ed6911d9ecaae1368d64d34..1688e51e73fdf58c299e96590cc1e28fc0cc7861 100644 (file)
@@ -27,7 +27,7 @@ public:
   FromShort(short s);
 };
 
-class FromShortExplicitly { // expected-note{{candidate is the implicit copy constructor}}
+class FromShortExplicitly { // expected-note{{candidate constructor (the implicit copy constructor)}}
 public:
   explicit FromShortExplicitly(short s);
 };
index f928626a03a57e3466afa7e4de79b8b9e7eb33a9..07ddb0add2cacfc2ecc4a4ccc059555e7d630cfd 100644 (file)
@@ -40,7 +40,7 @@ char cv[4] = { 'a', 's', 'd', 'f', 0 }; // expected-error{{excess elements in ar
 struct TooFew { int a; char* b; int c; }; 
 TooFew too_few = { 1, "asdf" }; // okay
 
-struct NoDefaultConstructor { // expected-note 3 {{candidate is the implicit copy constructor}} \
+struct NoDefaultConstructor { // expected-note 3 {{candidate constructor (the implicit copy constructor)}} \
                               // expected-note{{declared here}}
   NoDefaultConstructor(int); // expected-note 3 {{candidate constructor}}
 };
@@ -115,7 +115,7 @@ B2 b2_2 = { 4, d2, 0 };
 B2 b2_3 = { c2, a2, a2 };
 
 // C++ [dcl.init.aggr]p15:
-union u { int a; char* b; }; // expected-note{{candidate is the implicit copy constructor}}
+union u { int a; char* b; }; // expected-note{{candidate constructor (the implicit copy constructor)}}
 u u1 = { 1 }; 
 u u2 = u1; 
 u u3 = 1; // expected-error{{no viable conversion}}
index bc1cde5827bb8ec5443b420035c9fbd1b6849a7d..6601a3dd0d926ad1ef0983f957f498010c3cda43 100644 (file)
@@ -13,14 +13,14 @@ class Y {
   explicit Y(float);
 };
 
-class X { // expected-note{{candidate is the implicit copy constructor}}
+class X { // expected-note{{candidate constructor (the implicit copy constructor)}}
 public:
   explicit X(int); // expected-note{{candidate constructor}}
   X(float, float, float); // expected-note{{candidate constructor}}
   X(float, Y); // expected-note{{candidate constructor}}
 };
 
-class Z { // expected-note{{candidate is the implicit copy constructor}}
+class Z { // expected-note{{candidate constructor (the implicit copy constructor)}}
 public:
   Z(int); // expected-note{{candidate constructor}}
 };
index 946d4713f7572c747bb7191044065e3ac23a98c2..0bef0cd6be4c8fda9fe4c6ad7641cc36679e8b3f 100644 (file)
@@ -10,7 +10,7 @@ struct InitViaConstructor {
   InitViaConstructor(int i = 7);
 };
 
-struct NoValueInit { // expected-note 2 {{candidate is the implicit copy constructor}} 
+struct NoValueInit { // expected-note 2 {{candidate constructor (the implicit copy constructor)}} 
   NoValueInit(int i, int j); // expected-note 2 {{candidate constructor}}
 };
 
index 38b31f721a23c7f1fc8304c0ccef2b204f64566d..2a9d31fa945a59600078679e75ca228da99d3ab1 100644 (file)
@@ -9,7 +9,7 @@ int A; // expected-error {{redefinition of 'A' as different kind of symbol}}
 class A; // expected-error {{redefinition of 'A' as different kind of symbol}}
 
 class B {}; // expected-note {{previous definition is here}} \
-            // expected-note{{candidate is the implicit copy assignment operator}}
+            // expected-note{{candidate function (the implicit copy assignment operator)}}
 
 void C(); // expected-note {{previous definition is here}}
 namespace C {} // expected-error {{redefinition of 'C' as different kind of symbol}}
index a53231dca70ad59c90ece09ad2a6d47a9412c748..8618f0339bcafc2fe65d483523dda3b38204578d 100644 (file)
@@ -178,7 +178,7 @@ bool (foo_S::value);
 
 
 namespace somens {
-  struct a { }; // expected-note{{candidate is the implicit copy constructor}}
+  struct a { }; // expected-note{{candidate constructor (the implicit copy constructor)}}
 }
 
 template <typename T>
index 42bf029bd09289e11d07fe0089c36381735b2cbb..fbd26b2fd838a1bd592cc02b93f48bd84544f4d2 100644 (file)
@@ -304,7 +304,7 @@ namespace PR5756 {
 
 // Tests the exact text used to note the candidates
 namespace test1 {
-  template <class T> void foo(T t, unsigned N); // expected-note {{candidate function template specialization [with T = int]}}
+  template <class T> void foo(T t, unsigned N); // expected-note {{candidate function [with T = int]}}
   void foo(int n, char N); // expected-note {{candidate function}} 
 
   void test() {
index e9ffc2ad3f442514878029bc276e2c976b8f8c25..61c2e2110a99652ba2394bef71f761e82bc3e747 100644 (file)
@@ -59,7 +59,7 @@ void f(Short s, Long l, Enum1 e1, Enum2 e2, Xpmf pmf) {
   // FIXME: should pass (void)static_cast<no&>(islong(e1 % e2));
 }
 
-struct ShortRef { // expected-note{{candidate is the implicit copy assignment operator}}
+struct ShortRef { // expected-note{{candidate function (the implicit copy assignment operator)}}
   operator short&();
 };
 
@@ -67,7 +67,7 @@ struct LongRef {
   operator volatile long&();
 };
 
-struct XpmfRef { // expected-note{{candidate is the implicit copy assignment operator}}
+struct XpmfRef { // expected-note{{candidate function (the implicit copy assignment operator)}}
   operator pmf&();
 };
 
index 17f412f6716d60260b4f39b1e4bfe9d354b37a8d..7e3fa24197eb25b3c84ffe97eb82aff54db0acda 100644 (file)
@@ -2,7 +2,7 @@
 
 void f(void*, int); // expected-note{{candidate function}}
 template<typename T>
-  void f(T*, long); // expected-note{{candidate function template}}
+  void f(T*, long); // expected-note{{candidate function}}
 
 void test_f(int *ip, int i) {
   f(ip, i); // expected-error{{ambiguous}}
index 9ec2e9e0fe10bd8a654757f56a9acc4a4e2e6496..131b80cb1f36e2417cac7875c2cb2f5413ead88b 100644 (file)
@@ -5,7 +5,7 @@ class C { C(int a0 = 0); };
 template<>
 C<char>::C(int a0);
 
-struct S { }; // expected-note 3 {{candidate is the implicit copy constructor}}
+struct S { }; // expected-note 3 {{candidate constructor (the implicit copy constructor)}}
 
 template<typename T> void f1(T a, T b = 10) { } // expected-error{{no viable conversion}}
 
index c42ce26240e1bb8fa684fb84c5c702cda37c6f52..227856f1a8e22d08ec019a8f45cc33d5327f4757 100644 (file)
@@ -25,7 +25,7 @@ T X0<T>::value; // expected-error{{no matching constructor}}
 
 template int X0<int>::value;
 
-struct NotDefaultConstructible { // expected-note{{candidate is the implicit copy constructor}}
+struct NotDefaultConstructible { // expected-note{{candidate constructor (the implicit copy constructor)}}
   NotDefaultConstructible(int); // expected-note{{candidate constructor}}
 };
 
index b17a0faf7ca99a9f2d39ddfe7e9d173da32b8992..1c9b232f6d360d40e919ba78f1e335c61d027c08 100644 (file)
@@ -8,7 +8,7 @@
 // Fake typeid, lacking a typeinfo header.
 namespace std { class type_info {}; }
 
-struct dummy {}; // expected-note 3 {{candidate is the implicit copy constructor}}
+struct dummy {}; // expected-note 3 {{candidate constructor (the implicit copy constructor)}}
 
 template<typename T>
 int f0(T x) {
index 06fd2296c642d88b26753ba17e069523aa5fce41..428ef1ba87366ab51cc3c99bde8461a667afd3d3 100644 (file)
@@ -21,7 +21,7 @@ struct FunctionalCast0 {
 
 template struct FunctionalCast0<5>;
 
-struct X { // expected-note 3 {{candidate is the implicit copy constructor}}
+struct X { // expected-note 3 {{candidate constructor (the implicit copy constructor)}}
   X(int, int); // expected-note 3 {{candidate constructor}}
 };