From 1f127ffecb1499331b68cd9a6e21c6d50ebc57ec Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Fri, 17 Oct 2014 02:46:42 +0000 Subject: [PATCH] Towards PR21289: don't lose track of unexpanded parameter packs with non-dependent types, in CXXScalarValueInitExprs and in the nested-name-specifier or template arguments of a DeclRefExpr in particular. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@220028 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ExprCXX.h | 12 ++--- lib/AST/Expr.cpp | 45 +++++++------------ test/CXX/temp/temp.decls/temp.variadic/p5.cpp | 14 ++++++ 3 files changed, 37 insertions(+), 34 deletions(-) diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 57f3734b56..4995dfc065 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -1569,12 +1569,12 @@ class CXXScalarValueInitExpr : public Expr { public: /// \brief Create an explicitly-written scalar-value initialization /// expression. - CXXScalarValueInitExpr(QualType Type, - TypeSourceInfo *TypeInfo, - SourceLocation rParenLoc ) : - Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary, - false, false, Type->isInstantiationDependentType(), false), - RParenLoc(rParenLoc), TypeInfo(TypeInfo) {} + CXXScalarValueInitExpr(QualType Type, TypeSourceInfo *TypeInfo, + SourceLocation rParenLoc) + : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary, + false, false, Type->isInstantiationDependentType(), + Type->containsUnexpandedParameterPack()), + RParenLoc(rParenLoc), TypeInfo(TypeInfo) {} explicit CXXScalarValueInitExpr(EmptyShell Shell) : Expr(CXXScalarValueInitExprClass, Shell) { } diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index bc5498ad9a..fabcf0c10f 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -221,11 +221,11 @@ static void computeDeclRefDependence(const ASTContext &Ctx, NamedDecl *D, // (TD) C++ [temp.dep.expr]p3: // An id-expression is type-dependent if it contains: // - // and + // and // // (VD) C++ [temp.dep.constexpr]p2: // An identifier is value-dependent if it is: - + // (TD) - an identifier that was declared with dependent type // (VD) - a name declared with a dependent type, if (T->isDependentType()) { @@ -309,29 +309,11 @@ void DeclRefExpr::computeDependence(const ASTContext &Ctx) { bool InstantiationDependent = false; computeDeclRefDependence(Ctx, getDecl(), getType(), TypeDependent, ValueDependent, InstantiationDependent); - - // (TD) C++ [temp.dep.expr]p3: - // An id-expression is type-dependent if it contains: - // - // and - // - // (VD) C++ [temp.dep.constexpr]p2: - // An identifier is value-dependent if it is: - if (!TypeDependent && !ValueDependent && - hasExplicitTemplateArgs() && - TemplateSpecializationType::anyDependentTemplateArguments( - getTemplateArgs(), - getNumTemplateArgs(), - InstantiationDependent)) { - TypeDependent = true; - ValueDependent = true; - InstantiationDependent = true; - } - - ExprBits.TypeDependent = TypeDependent; - ExprBits.ValueDependent = ValueDependent; - ExprBits.InstantiationDependent = InstantiationDependent; - + + ExprBits.TypeDependent |= TypeDependent; + ExprBits.ValueDependent |= ValueDependent; + ExprBits.InstantiationDependent |= InstantiationDependent; + // Is the declaration a parameter pack? if (getDecl()->isParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -348,8 +330,14 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false), D(D), Loc(NameInfo.getLoc()), DNLoc(NameInfo.getInfo()) { DeclRefExprBits.HasQualifier = QualifierLoc ? 1 : 0; - if (QualifierLoc) + if (QualifierLoc) { getInternalQualifierLoc() = QualifierLoc; + auto *NNS = QualifierLoc.getNestedNameSpecifier(); + if (NNS->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; + if (NNS->containsUnexpandedParameterPack()) + ExprBits.ContainsUnexpandedParameterPack = true; + } DeclRefExprBits.HasFoundDecl = FoundD ? 1 : 0; if (FoundD) getInternalFoundDecl() = FoundD; @@ -364,8 +352,9 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, Dependent, InstantiationDependent, ContainsUnexpandedParameterPack); - if (InstantiationDependent) - setInstantiationDependent(true); + assert(!Dependent && "built a DeclRefExpr with dependent template args"); + ExprBits.InstantiationDependent |= InstantiationDependent; + ExprBits.ContainsUnexpandedParameterPack |= ContainsUnexpandedParameterPack; } else if (TemplateKWLoc.isValid()) { getTemplateKWAndArgsInfo()->initializeFrom(TemplateKWLoc); } diff --git a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp index dae6865666..8a70db6789 100644 --- a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp +++ b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp @@ -422,3 +422,17 @@ namespace PR16303 { B<1,2>::C<4,5,6> c1; // expected-note{{in instantiation of}} B<1,2,3,4>::C<4,5,6> c2; // expected-note{{in instantiation of}} } + +namespace PR21289 { + template using T = int; + template struct S { static const int value = 0; }; + template const int vt = 0; // expected-warning {{extension}} + int f(...); + template void g() { + f(T()...); + f(S>::value...); + f(vt>...); + } + template void g<>(); + template void g<1, 2, 3>(); +} -- 2.40.0