summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-02-03 20:40:30 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-02-03 20:40:30 +0000
commitdf18ee9620617192705da8791d4b63209e42bae7 (patch)
tree46ba26ffba0868a6a9dfd7db0d40eb746341348e /clang/lib/Sema
parent37acb79084b54b75d77687f4f575a07925517c83 (diff)
downloadbcm5719-llvm-df18ee9620617192705da8791d4b63209e42bae7.tar.gz
bcm5719-llvm-df18ee9620617192705da8791d4b63209e42bae7.zip
Ensure that we substitute into the declaration of a template parameter pack
(that is not a pack expansion) during template argument deduction, even if we deduced that the pack would be empty. llvm-svn: 259688
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaTemplateDeduction.cpp36
1 files changed, 32 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 2dc4fdb3201..0b090c8ff7e 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2119,8 +2119,25 @@ ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param,
PackedArgsBuilder.push_back(Output.pop_back_val());
}
- // FIXME: If the pack is empty and this is a template template parameter,
- // we still need to substitute into the parameter itself.
+ // 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.
+ LocalInstantiationScope Scope(S);
+ Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
+ TTP, Output,
+ Template->getSourceRange());
+ if (Inst.isInvalid())
+ return true;
+
+ TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
+ Output.data(), Output.size());
+ if (!S.SubstDecl(TTP, S.CurContext,
+ MultiLevelTemplateArgumentList(TemplateArgs)))
+ return true;
+ }
// Create the resulting argument pack.
Output.push_back(
@@ -2808,11 +2825,22 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
Builder.push_back(TemplateArgument(
llvm::makeArrayRef(ExplicitArgs, NumExplicitArgs)));
- // Forget the partially-substituted pack; it's substitution is now
+ // Forget the partially-substituted pack; its substitution is now
// complete.
CurrentInstantiationScope->ResetPartiallySubstitutedPack();
} else {
- Builder.push_back(TemplateArgument::getEmptyPack());
+ // Go through the motions of checking the empty argument pack against
+ // the parameter pack.
+ DeducedTemplateArgument DeducedPack(TemplateArgument::getEmptyPack());
+ if (ConvertDeducedTemplateArgument(*this, Param, DeducedPack,
+ FunctionTemplate, Info, true,
+ Builder)) {
+ Info.Param = makeTemplateParameter(Param);
+ // FIXME: These template arguments are temporary. Free them!
+ Info.reset(TemplateArgumentList::CreateCopy(Context, Builder.data(),
+ Builder.size()));
+ return TDK_SubstitutionFailure;
+ }
}
continue;
}
OpenPOWER on IntegriCloud