r179056 - Fix PR15634, better error message for template deduction failure.

Richard Trieu rtrieu at google.com
Mon Apr 8 14:11:41 PDT 2013


Author: rtrieu
Date: Mon Apr  8 16:11:40 2013
New Revision: 179056

URL: http://llvm.org/viewvc/llvm-project?rev=179056&view=rev
Log:
Fix PR15634, better error message for template deduction failure.

When two template decls with the same name are used in this diagnostic,
force them to print their qualified names.  This changes the bad message of:

candidate template ignored: could not match 'array' against 'array'

to the better message of:

candidate template ignored: could not match 'NS2::array' against 'NS1::array'

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/SemaTemplate/overload-candidates.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=179056&r1=179055&r2=179056&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Apr  8 16:11:40 2013
@@ -2370,6 +2370,11 @@ def note_ovl_candidate_failed_overload_r
     "function %0">;
 def note_ovl_candidate_non_deduced_mismatch : Note<
     "candidate template ignored: could not match %diff{$ against $|types}0,1">;
+// This note is needed because the above note would sometimes print two
+// different types with the same name.  Remove this note when the above note
+// can handle that case properly.
+def note_ovl_candidate_non_deduced_mismatch_qualified : Note<
+    "candidate template ignored: could not match %q0 against %q1">;
     
 // Note that we don't treat templates differently for this diagnostic.
 def note_ovl_candidate_arity : Note<"candidate "

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=179056&r1=179055&r2=179056&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Apr  8 16:11:40 2013
@@ -8508,13 +8508,35 @@ void DiagnoseBadDeduction(Sema &S, Overl
     return;
   }
 
-  case Sema::TDK_NonDeducedMismatch:
+  case Sema::TDK_NonDeducedMismatch: {
     // FIXME: Provide a source location to indicate what we couldn't match.
+    TemplateArgument FirstTA = *Cand->DeductionFailure.getFirstArg();
+    TemplateArgument SecondTA = *Cand->DeductionFailure.getSecondArg();
+    if (FirstTA.getKind() == TemplateArgument::Template &&
+        SecondTA.getKind() == TemplateArgument::Template) {
+      TemplateName FirstTN = FirstTA.getAsTemplate();
+      TemplateName SecondTN = SecondTA.getAsTemplate();
+      if (FirstTN.getKind() == TemplateName::Template &&
+          SecondTN.getKind() == TemplateName::Template) {
+        if (FirstTN.getAsTemplateDecl()->getName() ==
+            SecondTN.getAsTemplateDecl()->getName()) {
+          // FIXME: This fixes a bad diagnostic where both templates are named
+          // the same.  This particular case is a bit difficult since:
+          // 1) It is passed as a string to the diagnostic printer.
+          // 2) The diagnostic printer only attempts to find a better
+          //    name for types, not decls.
+          // Ideally, this should folded into the diagnostic printer.
+          S.Diag(Fn->getLocation(),
+                 diag::note_ovl_candidate_non_deduced_mismatch_qualified)
+              << FirstTN.getAsTemplateDecl() << SecondTN.getAsTemplateDecl();
+          return;
+        }
+      }
+    }
     S.Diag(Fn->getLocation(), diag::note_ovl_candidate_non_deduced_mismatch)
-      << *Cand->DeductionFailure.getFirstArg()
-      << *Cand->DeductionFailure.getSecondArg();
+      << FirstTA << SecondTA;
     return;
-
+  }
   // TODO: diagnose these individually, then kill off
   // note_ovl_candidate_bad_deduction, which is uselessly vague.
   case Sema::TDK_MiscellaneousDeductionFailure:

Modified: cfe/trunk/test/SemaTemplate/overload-candidates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/overload-candidates.cpp?rev=179056&r1=179055&r2=179056&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/overload-candidates.cpp (original)
+++ cfe/trunk/test/SemaTemplate/overload-candidates.cpp Mon Apr  8 16:11:40 2013
@@ -62,3 +62,20 @@ template<typename T> struct NonTemplateF
   typename boost::enable_if<sizeof(T) == 4, int>::type f(); // expected-error{{no type named 'type' in 'boost::enable_if<false, int>'; 'enable_if' cannot be used to disable this declaration}}
 };
 NonTemplateFunction<char> NTFC; // expected-note{{here}}
+
+namespace NS1 {
+  template <class A>
+  class array {};
+}
+
+namespace NS2 {
+  template <class A>
+  class array {};
+}
+
+template <class A>
+void foo(NS2::array<A>); // expected-note{{candidate template ignored: could not match 'NS2::array' against 'NS1::array'}}
+
+void test() {
+  foo(NS1::array<int>()); // expected-error{{no matching function for call to 'foo'}}
+}





More information about the cfe-commits mailing list