]> granicus.if.org Git - clang/commitdiff
C++ constant expression handling: eagerly instantiate static const integral data
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 21 Dec 2011 00:25:33 +0000 (00:25 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 21 Dec 2011 00:25:33 +0000 (00:25 +0000)
members of class templates so that their values can be used in ICEs. This
required reverting r105465, to get such instantiated members to be included in
serialized ASTs.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147023 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
test/PCH/chain-cxx.cpp
test/SemaTemplate/instantiate-declref-ice.cpp

index 65439032f2c29174f1294ad634213ce0fd7a5acf..3a61fe50666aab564ac6e3c68ce7b87407a73df0 100644 (file)
@@ -9526,7 +9526,12 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
         // This is a modification of an existing AST node. Notify listeners.
         if (ASTMutationListener *L = getASTMutationListener())
           L->StaticDataMemberInstantiated(Var);
-        PendingInstantiations.push_back(std::make_pair(Var, Loc));
+        QualType T = Var->getType();
+        if (T.isConstQualified() && !T.isVolatileQualified() &&
+            T->isIntegralOrEnumerationType())
+          InstantiateStaticDataMemberDefinition(Loc, Var);
+        else
+          PendingInstantiations.push_back(std::make_pair(Var, Loc));
       }
     }
 
index b2208b63c87fcf5918cc70b518473b6fdc6c054f..53adf68cd97c6cae9be412a73e4057ba252b4dcf 100644 (file)
@@ -359,8 +359,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
   SemaRef.CheckVariableDeclaration(Var, Previous);
 
   if (D->isOutOfLine()) {
-    if (!D->isStaticDataMember())
-      D->getLexicalDeclContext()->addDecl(Var);
+    D->getLexicalDeclContext()->addDecl(Var);
     Owner->makeDeclVisibleInContext(Var);
   } else {
     Owner->addDecl(Var);
index c42ee7d39eeb8012bf44fce285062d6a96199388..0d50e61c5a956f426d538903a139bbf53eba3726 100644 (file)
@@ -38,9 +38,12 @@ template<typename T> struct TestBaseSpecifiers2 : TestBaseSpecifiers<T> { };
 template <typename T>
 struct TS3 {
   static const int value = 0;
+  static const int value2;
 };
 template <typename T>
 const int TS3<T>::value;
+template <typename T>
+const int TS3<T>::value2 = 1;
 // Instantiate struct, but not value.
 struct instantiate : TS3<int> {};
 
@@ -96,8 +99,9 @@ struct TestBaseSpecifiers4 : TestBaseSpecifiers3 { };
 struct A { };
 struct B : A { };
 
-// Instantiate TS3's member.
+// Instantiate TS3's members.
 static const int ts3m1 = TS3<int>::value;
+extern int arr[TS3<int>::value2];
 
 // Redefinition of typedef
 typedef int Integer;
@@ -132,6 +136,7 @@ void test() {
 
 // Should have remembered that there is a definition.
 static const int ts3m2 = TS3<int>::value;
+int arr[TS3<int>::value2];
 
 //===----------------------------------------------------------------------===//
 #endif
index 0f3c08b05620b8a9fe7a848de3ca41a299ea26f3..49b1b63f51523e39bacd7e5bdf0a11a90efcd73c 100644 (file)
@@ -31,4 +31,4 @@ struct X1 {
 template<typename T>
 const unsigned X1<T>::value = sizeof(T);
 
-int array3[X1<int>::value == sizeof(int)? 1 : -1]; // expected-error{{variable length array declaration not allowed at file scope}}
+int array3[X1<int>::value == sizeof(int)? 1 : -1];