]> granicus.if.org Git - clang/commitdiff
PR18246: When performing template argument deduction to decide which template
authorRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 14 Dec 2013 03:18:05 +0000 (03:18 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 14 Dec 2013 03:18:05 +0000 (03:18 +0000)
is specialized by an explicit specialization, start from the first declaration
in case we've got a member of a class template (redeclarations might not number
the template parameters the same way).

Our recover here is still far from ideal.

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

lib/Sema/SemaTemplate.cpp
test/SemaTemplate/explicit-specialization-member.cpp

index b134f6ea51070a3b34dcacc586fc5b77fa5bb8a1..e4fa380c3dbede437d9547d68e3bb0b5cc998305 100644 (file)
@@ -6521,9 +6521,9 @@ bool Sema::CheckFunctionTemplateSpecialization(
       // FIXME: It is somewhat wasteful to build
       TemplateDeductionInfo Info(FailedCandidates.getLocation());
       FunctionDecl *Specialization = 0;
-      if (TemplateDeductionResult TDK
-            = DeduceTemplateArguments(FunTmpl, ExplicitTemplateArgs, FT,
-                                      Specialization, Info)) {
+      if (TemplateDeductionResult TDK = DeduceTemplateArguments(
+              cast<FunctionTemplateDecl>(FunTmpl->getFirstDecl()),
+              ExplicitTemplateArgs, FT, Specialization, Info)) {
         // Template argument deduction failed; record why it failed, so
         // that we can provide nifty diagnostics.
         FailedCandidates.addCandidate()
index 9ddbc04953d3cdb4b020047bb0fddf5ef4cc7242..07d73894468fdcbf284991a7aeb53af08274c3fb 100644 (file)
@@ -28,3 +28,22 @@ namespace PR12331 {
   };
   template<> struct S<int>::U { static const int n = sizeof(int); }; // expected-error {{explicit specialization of 'U' after instantiation}}
 }
+
+namespace PR18246 {
+  template<typename T>
+  class Baz {
+  public:
+    template<int N> void bar();
+  };
+
+  template<typename T>
+  template<int N>
+  void Baz<T>::bar() {
+  }
+
+  // FIXME: Don't suggest the 'template<>' correction here, because this cannot
+  // be an explicit specialization.
+  template<typename T>
+  void Baz<T>::bar<0>() { // expected-error {{requires 'template<>'}}
+  }
+}