r249114 - PR24921: checking explicitly-specified template arguments when matching a

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 1 17:49:38 PDT 2015


Author: rsmith
Date: Thu Oct  1 19:49:37 2015
New Revision: 249114

URL: http://llvm.org/viewvc/llvm-project?rev=249114&view=rev
Log:
PR24921: checking explicitly-specified template arguments when matching a
partial specialization can perform conversions on the argument. Be sure we
start again from the original argument when checking each possible template.

Modified:
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=249114&r1=249113&r2=249114&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Oct  1 19:49:37 2015
@@ -3923,7 +3923,7 @@ bool Sema::CheckTemplateArgumentList(Tem
 
   // No problems found with the new argument list, propagate changes back
   // to caller.
-  TemplateArgs = NewArgs;
+  TemplateArgs = std::move(NewArgs);
 
   return false;
 }
@@ -6756,6 +6756,9 @@ bool Sema::CheckFunctionTemplateSpeciali
   UnresolvedSet<8> Candidates;
   TemplateSpecCandidateSet FailedCandidates(FD->getLocation());
 
+  llvm::SmallDenseMap<FunctionDecl *, TemplateArgumentListInfo, 8>
+      ConvertedTemplateArgs;
+
   DeclContext *FDLookupContext = FD->getDeclContext()->getRedeclContext();
   for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
          I != E; ++I) {
@@ -6785,6 +6788,10 @@ bool Sema::CheckFunctionTemplateSpeciali
         }
       }
 
+      TemplateArgumentListInfo Args;
+      if (ExplicitTemplateArgs)
+        Args = *ExplicitTemplateArgs;
+
       // C++ [temp.expl.spec]p11:
       //   A trailing template-argument can be left unspecified in the
       //   template-id naming an explicit function template specialization
@@ -6796,7 +6803,7 @@ bool Sema::CheckFunctionTemplateSpeciali
       FunctionDecl *Specialization = nullptr;
       if (TemplateDeductionResult TDK = DeduceTemplateArguments(
               cast<FunctionTemplateDecl>(FunTmpl->getFirstDecl()),
-              ExplicitTemplateArgs, FT, Specialization, Info)) {
+              ExplicitTemplateArgs ? &Args : nullptr, FT, Specialization, Info)) {
         // Template argument deduction failed; record why it failed, so
         // that we can provide nifty diagnostics.
         FailedCandidates.addCandidate()
@@ -6807,6 +6814,8 @@ bool Sema::CheckFunctionTemplateSpeciali
       }
 
       // Record this candidate.
+      if (ExplicitTemplateArgs)
+        ConvertedTemplateArgs[Specialization] = std::move(Args);
       Candidates.addDecl(Specialization, I.getAccess());
     }
   }
@@ -6885,10 +6894,10 @@ bool Sema::CheckFunctionTemplateSpeciali
   // Take copies of (semantic and syntactic) template argument lists.
   const TemplateArgumentList* TemplArgs = new (Context)
     TemplateArgumentList(Specialization->getTemplateSpecializationArgs());
-  FD->setFunctionTemplateSpecialization(Specialization->getPrimaryTemplate(),
-                                        TemplArgs, /*InsertPos=*/nullptr,
-                                    SpecInfo->getTemplateSpecializationKind(),
-                                        ExplicitTemplateArgs);
+  FD->setFunctionTemplateSpecialization(
+      Specialization->getPrimaryTemplate(), TemplArgs, /*InsertPos=*/nullptr,
+      SpecInfo->getTemplateSpecializationKind(),
+      ExplicitTemplateArgs ? &ConvertedTemplateArgs[Specialization] : nullptr);
 
   // The "previous declaration" for this function template specialization is
   // the prior function template specialization.

Modified: cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp?rev=249114&r1=249113&r2=249114&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp (original)
+++ cfe/trunk/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp Thu Oct  1 19:49:37 2015
@@ -148,3 +148,10 @@ namespace DeclMatch {
   template<typename T, T> int f() { return X<T>::n; }
   int k = f<int, 0>(); // ok, friend
 }
+
+namespace PR24921 {
+  enum E { e };
+  template<E> void f();
+  template<int> void f(int);
+  template<> void f<e>() {}
+}




More information about the cfe-commits mailing list