From: Richard Smith Date: Wed, 14 Feb 2018 02:07:53 +0000 (+0000) Subject: Fix a couple of places where we assumed that non-type template parameters are always... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d0f176e8eb6c5cc7c1e89436b25692baedd6aca1;p=clang Fix a couple of places where we assumed that non-type template parameters are always rvalues. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@325095 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 3fb2c6130f..e51ffb6d5b 100644 --- a/include/clang/AST/ExprCXX.h +++ b/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/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index a0d6113811..b8a837fe47 100644 --- a/lib/AST/ExprCXX.cpp +++ b/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/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 489d026027..2c4f649078 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/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/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index c33a1fc2ec..7d52394bd7 100644 --- a/lib/Sema/TreeTransform.h +++ b/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/test/SemaTemplate/nested-template.cpp b/test/SemaTemplate/nested-template.cpp index 44cb82e95b..efbde2076b 100644 --- a/test/SemaTemplate/nested-template.cpp +++ b/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/test/SemaTemplate/sizeof-pack.cpp b/test/SemaTemplate/sizeof-pack.cpp new file mode 100644 index 0000000000..4b0c883a24 --- /dev/null +++ b/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<>();