diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 3fb2c6130f86..e51ffb6d5bee 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -3916,6 +3916,7 @@ class SubstNonTypeTemplateParmPackExpr : public Expr { public: SubstNonTypeTemplateParmPackExpr(QualType T, + ExprValueKind ValueKind, NonTypeTemplateParmDecl *Param, SourceLocation NameLoc, const TemplateArgument &ArgPack); diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index a0d611381123..b8a837fe47b4 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -1330,10 +1330,11 @@ SizeOfPackExpr *SizeOfPackExpr::CreateDeserialized(ASTContext &Context, SubstNonTypeTemplateParmPackExpr:: SubstNonTypeTemplateParmPackExpr(QualType T, + ExprValueKind ValueKind, NonTypeTemplateParmDecl *Param, SourceLocation NameLoc, const TemplateArgument &ArgPack) - : Expr(SubstNonTypeTemplateParmPackExprClass, T, VK_RValue, OK_Ordinary, + : Expr(SubstNonTypeTemplateParmPackExprClass, T, ValueKind, OK_Ordinary, true, true, true, true), Param(Param), Arguments(ArgPack.pack_begin()), NumArguments(ArgPack.pack_size()), NameLoc(NameLoc) {} diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 489d026027de..2c4f6490789e 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1212,11 +1212,11 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E, NTTP->getDeclName()); if (TargetType.isNull()) return ExprError(); - - return new (SemaRef.Context) SubstNonTypeTemplateParmPackExpr(TargetType, - NTTP, - E->getLocation(), - Arg); + + return new (SemaRef.Context) SubstNonTypeTemplateParmPackExpr( + TargetType.getNonLValueExprType(SemaRef.Context), + TargetType->isReferenceType() ? VK_LValue : VK_RValue, NTTP, + E->getLocation(), Arg); } Arg = getPackSubstitutedTemplateArgument(getSema(), Arg); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index c33a1fc2ecfa..7d52394bd7ab 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -11392,8 +11392,10 @@ TreeTransform::TransformSizeOfPackExpr(SizeOfPackExpr *E) { ArgStorage = TemplateArgument(TemplateName(TTPD), None); } else { auto *VD = cast(Pack); - ExprResult DRE = getSema().BuildDeclRefExpr(VD, VD->getType(), - VK_RValue, E->getPackLoc()); + ExprResult DRE = getSema().BuildDeclRefExpr( + VD, VD->getType().getNonLValueExprType(getSema().Context), + VD->getType()->isReferenceType() ? VK_LValue : VK_RValue, + E->getPackLoc()); if (DRE.isInvalid()) return ExprError(); ArgStorage = new (getSema().Context) PackExpansionExpr( diff --git a/clang/test/SemaTemplate/nested-template.cpp b/clang/test/SemaTemplate/nested-template.cpp index 44cb82e95bbf..efbde2076b9f 100644 --- a/clang/test/SemaTemplate/nested-template.cpp +++ b/clang/test/SemaTemplate/nested-template.cpp @@ -161,3 +161,10 @@ class Outer1 { template struct X; template int X::func() {} // expected-error{{out-of-line definition of 'func' from class 'X' without definition}} }; + +namespace RefPack { + template struct A { template void f(T (&...t)[N]); }; + constexpr int k = 10; + int arr[10]; + void g() { A().f(arr); } +} diff --git a/clang/test/SemaTemplate/sizeof-pack.cpp b/clang/test/SemaTemplate/sizeof-pack.cpp new file mode 100644 index 000000000000..4b0c883a24ac --- /dev/null +++ b/clang/test/SemaTemplate/sizeof-pack.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s +// expected-no-diagnostics + +template int f() { + return sizeof...(Ns); +} +template int f<>();