From: Richard Smith Date: Thu, 20 Apr 2017 01:15:31 +0000 (+0000) Subject: PR32673: Don't wrap parameter packs in SubstTemplateTypeParmPackType nodes when formi... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6a8a5b41549721c36fa6b68232d300c64050d047;p=clang PR32673: Don't wrap parameter packs in SubstTemplateTypeParmPackType nodes when forming implicit deduction guides. Doing so thwarts template type deduction. Instead, substitute the pack directly by picking "slice 0" of the resulting expansion. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@300805 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index 525f848a9f..ad95f6f8ef 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -1544,7 +1544,11 @@ class DependentSizedArrayTypeLoc : public InheritingConcreteTypeLoc { - +public: + void initializeLocal(ASTContext &Context, SourceLocation Loc) { + ArrayTypeLoc::initializeLocal(Context, Loc); + setSizeExpr(getTypePtr()->getSizeExpr()); + } }; class VariableArrayTypeLoc : diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index f522e76b06..61b4df4096 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -1636,11 +1636,22 @@ private: transformFunctionTypeParam(ParmVarDecl *OldParam, MultiLevelTemplateArgumentList &Args) { TypeSourceInfo *OldDI = OldParam->getTypeSourceInfo(); - TypeSourceInfo *NewDI = - Args.getNumLevels() - ? SemaRef.SubstType(OldDI, Args, OldParam->getLocation(), - OldParam->getDeclName()) - : OldDI; + TypeSourceInfo *NewDI; + if (!Args.getNumLevels()) + NewDI = OldDI; + else if (auto PackTL = OldDI->getTypeLoc().getAs()) { + // Expand out the one and only element in each inner pack. + Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, 0); + NewDI = + SemaRef.SubstType(PackTL.getPatternLoc(), Args, + OldParam->getLocation(), OldParam->getDeclName()); + if (!NewDI) return nullptr; + NewDI = + SemaRef.CheckPackExpansion(NewDI, PackTL.getEllipsisLoc(), + PackTL.getTypePtr()->getNumExpansions()); + } else + NewDI = SemaRef.SubstType(OldDI, Args, OldParam->getLocation(), + OldParam->getDeclName()); if (!NewDI) return nullptr; diff --git a/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp b/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp index d6374e4ce9..5de228ad28 100644 --- a/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp +++ b/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp @@ -213,3 +213,38 @@ namespace transform_params { }; D d(Y<0, 1, 2>{}); } + +namespace variadic { + int arr3[3], arr4[4]; + + // PR32673 + template struct A { + template A(T, U...); + }; + A a(1, 2, 3); + + template struct B { + template B(T, int (&...r)[N]); + }; + B b(1, arr3, arr4); + + template struct C { + template typename ...U> C(T, U...); + }; + C c(1, a, b); + + template struct X { + template X(T, U...); + }; + X x(1, 2, 3); + + template struct Y { + template Y(T, int (&...r)[N]); + }; + Y y(1, arr3, arr4); + + template typename ...U> struct Z { + template Z(T, U...); + }; + Z z(1, a, b); +}