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