Fix a couple of places where we assumed that non-type template parameters are always rvalues.

llvm-svn: 325095
This commit is contained in:
Richard Smith 2018-02-14 02:07:53 +00:00
parent 1d76120d9a
commit f1f20e6802
6 changed files with 26 additions and 8 deletions

View File

@ -3916,6 +3916,7 @@ class SubstNonTypeTemplateParmPackExpr : public Expr {
public: public:
SubstNonTypeTemplateParmPackExpr(QualType T, SubstNonTypeTemplateParmPackExpr(QualType T,
ExprValueKind ValueKind,
NonTypeTemplateParmDecl *Param, NonTypeTemplateParmDecl *Param,
SourceLocation NameLoc, SourceLocation NameLoc,
const TemplateArgument &ArgPack); const TemplateArgument &ArgPack);

View File

@ -1330,10 +1330,11 @@ SizeOfPackExpr *SizeOfPackExpr::CreateDeserialized(ASTContext &Context,
SubstNonTypeTemplateParmPackExpr:: SubstNonTypeTemplateParmPackExpr::
SubstNonTypeTemplateParmPackExpr(QualType T, SubstNonTypeTemplateParmPackExpr(QualType T,
ExprValueKind ValueKind,
NonTypeTemplateParmDecl *Param, NonTypeTemplateParmDecl *Param,
SourceLocation NameLoc, SourceLocation NameLoc,
const TemplateArgument &ArgPack) const TemplateArgument &ArgPack)
: Expr(SubstNonTypeTemplateParmPackExprClass, T, VK_RValue, OK_Ordinary, : Expr(SubstNonTypeTemplateParmPackExprClass, T, ValueKind, OK_Ordinary,
true, true, true, true), true, true, true, true),
Param(Param), Arguments(ArgPack.pack_begin()), Param(Param), Arguments(ArgPack.pack_begin()),
NumArguments(ArgPack.pack_size()), NameLoc(NameLoc) {} NumArguments(ArgPack.pack_size()), NameLoc(NameLoc) {}

View File

@ -1212,11 +1212,11 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
NTTP->getDeclName()); NTTP->getDeclName());
if (TargetType.isNull()) if (TargetType.isNull())
return ExprError(); return ExprError();
return new (SemaRef.Context) SubstNonTypeTemplateParmPackExpr(TargetType, return new (SemaRef.Context) SubstNonTypeTemplateParmPackExpr(
NTTP, TargetType.getNonLValueExprType(SemaRef.Context),
E->getLocation(), TargetType->isReferenceType() ? VK_LValue : VK_RValue, NTTP,
Arg); E->getLocation(), Arg);
} }
Arg = getPackSubstitutedTemplateArgument(getSema(), Arg); Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);

View File

@ -11392,8 +11392,10 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
ArgStorage = TemplateArgument(TemplateName(TTPD), None); ArgStorage = TemplateArgument(TemplateName(TTPD), None);
} else { } else {
auto *VD = cast<ValueDecl>(Pack); auto *VD = cast<ValueDecl>(Pack);
ExprResult DRE = getSema().BuildDeclRefExpr(VD, VD->getType(), ExprResult DRE = getSema().BuildDeclRefExpr(
VK_RValue, E->getPackLoc()); VD, VD->getType().getNonLValueExprType(getSema().Context),
VD->getType()->isReferenceType() ? VK_LValue : VK_RValue,
E->getPackLoc());
if (DRE.isInvalid()) if (DRE.isInvalid())
return ExprError(); return ExprError();
ArgStorage = new (getSema().Context) PackExpansionExpr( ArgStorage = new (getSema().Context) PackExpansionExpr(

View File

@ -161,3 +161,10 @@ class Outer1 {
template <typename T> struct X; template <typename T> struct X;
template <typename T> int X<T>::func() {} // expected-error{{out-of-line definition of 'func' from class 'X<T>' without definition}} template <typename T> int X<T>::func() {} // expected-error{{out-of-line definition of 'func' from class 'X<T>' without definition}}
}; };
namespace RefPack {
template<const int &...N> struct A { template<typename ...T> void f(T (&...t)[N]); };
constexpr int k = 10;
int arr[10];
void g() { A<k>().f(arr); }
}

View File

@ -0,0 +1,7 @@
// RUN: %clang_cc1 -std=c++11 -verify %s
// expected-no-diagnostics
template<int &...Ns> int f() {
return sizeof...(Ns);
}
template int f<>();