r220028 - Towards PR21289: don't lose track of unexpanded parameter packs with

Richard Smith richard-llvm at metafoo.co.uk
Thu Oct 16 19:46:43 PDT 2014


Author: rsmith
Date: Thu Oct 16 21:46:42 2014
New Revision: 220028

URL: http://llvm.org/viewvc/llvm-project?rev=220028&view=rev
Log:
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.

Modified:
    cfe/trunk/include/clang/AST/ExprCXX.h
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p5.cpp

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=220028&r1=220027&r2=220028&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Thu Oct 16 21:46:42 2014
@@ -1569,12 +1569,12 @@ class CXXScalarValueInitExpr : public Ex
 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) { }

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=220028&r1=220027&r2=220028&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Thu Oct 16 21:46:42 2014
@@ -221,11 +221,11 @@ static void computeDeclRefDependence(con
   // (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(cons
   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 ASTContex
   : 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 ASTContex
                                                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);
   }

Modified: cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p5.cpp?rev=220028&r1=220027&r2=220028&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p5.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p5.cpp Thu Oct 16 21:46:42 2014
@@ -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<int> using T = int;
+  template<typename> struct S { static const int value = 0; };
+  template<typename> const int vt = 0; // expected-warning {{extension}}
+  int f(...);
+  template<int ...Ns> void g() {
+    f(T<Ns>()...);
+    f(S<T<Ns>>::value...);
+    f(vt<T<Ns>>...);
+  }
+  template void g<>();
+  template void g<1, 2, 3>();
+}





More information about the cfe-commits mailing list