r290403 - Only substitute into type of non-type template parameter once, rather than
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Thu Dec 22 18:00:24 PST 2016
Author: rsmith
Date: Thu Dec 22 20:00:24 2016
New Revision: 290403
URL: http://llvm.org/viewvc/llvm-project?rev=290403&view=rev
Log:
Only substitute into type of non-type template parameter once, rather than
twice, in finalization of template argument deduction.
This is a re-commit of r290310 (reverted in r290329); the bug found by the
buildbots was fixed in r290399 (we would sometimes build a deduced template
argument with a bogus type).
Modified:
cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=290403&r1=290402&r2=290403&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Thu Dec 22 20:00:24 2016
@@ -2072,7 +2072,8 @@ static bool isSameTemplateArg(ASTContext
///
/// \param NTTPType For a declaration template argument, the type of
/// the non-type template parameter that corresponds to this template
-/// argument.
+/// argument. Can be null if no type sugar is available to add to the
+/// type from the template argument.
///
/// \param Loc The source location to use for the resulting template
/// argument.
@@ -2088,12 +2089,16 @@ Sema::getTrivialTemplateArgumentLoc(cons
Arg, Context.getTrivialTypeSourceInfo(Arg.getAsType(), Loc));
case TemplateArgument::Declaration: {
+ if (NTTPType.isNull())
+ NTTPType = Arg.getParamTypeForDecl();
Expr *E = BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc)
.getAs<Expr>();
return TemplateArgumentLoc(TemplateArgument(E), E);
}
case TemplateArgument::NullPtr: {
+ if (NTTPType.isNull())
+ NTTPType = Arg.getNullPtrType();
Expr *E = BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc)
.getAs<Expr>();
return TemplateArgumentLoc(TemplateArgument(NTTPType, /*isNullPtr*/true),
@@ -2144,31 +2149,13 @@ ConvertDeducedTemplateArgument(Sema &S,
TemplateDeductionInfo &Info,
bool InFunctionTemplate,
SmallVectorImpl<TemplateArgument> &Output) {
- // First, for a non-type template parameter type that is
- // initialized by a declaration, we need the type of the
- // corresponding non-type template parameter.
- QualType NTTPType;
- if (NonTypeTemplateParmDecl *NTTP =
- dyn_cast<NonTypeTemplateParmDecl>(Param)) {
- NTTPType = NTTP->getType();
- if (NTTPType->isDependentType()) {
- TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Output);
- NTTPType = S.SubstType(NTTPType,
- MultiLevelTemplateArgumentList(TemplateArgs),
- NTTP->getLocation(),
- NTTP->getDeclName());
- if (NTTPType.isNull())
- return true;
- }
- }
-
auto ConvertArg = [&](DeducedTemplateArgument Arg,
unsigned ArgumentPackIndex) {
// Convert the deduced template argument into a template
// argument that we can check, almost as if the user had written
// the template argument explicitly.
TemplateArgumentLoc ArgLoc =
- S.getTrivialTemplateArgumentLoc(Arg, NTTPType, Info.getLocation());
+ S.getTrivialTemplateArgumentLoc(Arg, QualType(), Info.getLocation());
// Check the template argument, converting it as necessary.
return S.CheckTemplateArgument(
@@ -2200,22 +2187,28 @@ ConvertDeducedTemplateArgument(Sema &S,
}
// If the pack is empty, we still need to substitute into the parameter
- // itself, in case that substitution fails. For non-type parameters, we did
- // this above. For type parameters, no substitution is ever required.
- auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param);
- if (TTP && PackedArgsBuilder.empty()) {
- // Set up a template instantiation context.
+ // itself, in case that substitution fails.
+ if (PackedArgsBuilder.empty()) {
LocalInstantiationScope Scope(S);
- Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
- TTP, Output,
- Template->getSourceRange());
- if (Inst.isInvalid())
- return true;
-
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Output);
- if (!S.SubstDecl(TTP, S.CurContext,
- MultiLevelTemplateArgumentList(TemplateArgs)))
- return true;
+ MultiLevelTemplateArgumentList Args(TemplateArgs);
+
+ if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
+ Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
+ NTTP, Output,
+ Template->getSourceRange());
+ if (Inst.isInvalid() ||
+ S.SubstType(NTTP->getType(), Args, NTTP->getLocation(),
+ NTTP->getDeclName()).isNull())
+ return true;
+ } else if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
+ Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
+ TTP, Output,
+ Template->getSourceRange());
+ if (Inst.isInvalid() || !S.SubstDecl(TTP, S.CurContext, Args))
+ return true;
+ }
+ // For type parameters, no substitution is ever required.
}
// Create the resulting argument pack.
More information about the cfe-commits
mailing list