diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-02-21 06:30:38 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-02-21 06:30:38 +0000 |
commit | 735b586081cd2e830b82fe1edd19a173e3512a60 (patch) | |
tree | 08101d45975c90d58f3333905c256aa32fc0803f /lib/Sema/SemaTemplateInstantiate.cpp | |
parent | d4c85a8040ce7d08cab2fce51d3516a6c4bc973d (diff) |
PR32010: Fix template argument depth mixup when forming implicit constructor
template deduction guides for class template argument deduction.
Ensure that we have a local instantiation scope for tracking the instantiated
parameters. Additionally, unusually, we're substituting at depth 1 and leaving
depth 0 alone; make sure that we don't reduce template parameter depth by 2 for
inner parameters in the process. (This is probably also broken for alias
templates in the case where they're expanded within a dependent context, but
this patch doesn't fix that.)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@295696 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 723a6c0e4d..f7535e6d24 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -1121,6 +1121,23 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E, return E; TemplateArgument Arg = TemplateArgs(NTTP->getDepth(), NTTP->getPosition()); + + if (TemplateArgs.getNumLevels() != TemplateArgs.getNumSubstitutedLevels()) { + // We're performing a partial substitution, so the substituted argument + // could be dependent. As a result we can't create a SubstNonType*Expr + // node now, since that represents a fully-substituted argument. + // FIXME: We should have some AST representation for this. + if (Arg.getKind() == TemplateArgument::Pack) { + // FIXME: This won't work for alias templates. + assert(Arg.pack_size() == 1 && Arg.pack_begin()->isPackExpansion() && + "unexpected pack arguments in partial substitution"); + Arg = Arg.pack_begin()->getPackExpansionPattern(); + } + assert(Arg.getKind() == TemplateArgument::Expression && + "unexpected nontype template argument kind in partial substitution"); + return Arg.getAsExpr(); + } + if (NTTP->isParameterPack()) { assert(Arg.getKind() == TemplateArgument::Pack && "Missing argument pack"); @@ -1429,12 +1446,9 @@ TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB, NewTTPDecl = cast_or_null<TemplateTypeParmDecl>( TransformDecl(TL.getNameLoc(), OldTTPDecl)); - QualType Result - = getSema().Context.getTemplateTypeParmType(T->getDepth() - - TemplateArgs.getNumLevels(), - T->getIndex(), - T->isParameterPack(), - NewTTPDecl); + QualType Result = getSema().Context.getTemplateTypeParmType( + T->getDepth() - TemplateArgs.getNumSubstitutedLevels(), T->getIndex(), + T->isParameterPack(), NewTTPDecl); TemplateTypeParmTypeLoc NewTL = TLB.push<TemplateTypeParmTypeLoc>(Result); NewTL.setNameLoc(TL.getNameLoc()); return Result; |