From: Richard Smith Date: Wed, 21 Dec 2011 00:25:33 +0000 (+0000) Subject: C++ constant expression handling: eagerly instantiate static const integral data X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3e9ea0b8cd7c4691d62e385245556be5fded58a7;p=clang C++ constant expression handling: eagerly instantiate static const integral data 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 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 65439032f2..3a61fe5066 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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)); } } diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index b2208b63c8..53adf68cd9 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -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); diff --git a/test/PCH/chain-cxx.cpp b/test/PCH/chain-cxx.cpp index c42ee7d39e..0d50e61c5a 100644 --- a/test/PCH/chain-cxx.cpp +++ b/test/PCH/chain-cxx.cpp @@ -38,9 +38,12 @@ template struct TestBaseSpecifiers2 : TestBaseSpecifiers { }; template struct TS3 { static const int value = 0; + static const int value2; }; template const int TS3::value; +template +const int TS3::value2 = 1; // Instantiate struct, but not value. struct instantiate : TS3 {}; @@ -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::value; +extern int arr[TS3::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::value; +int arr[TS3::value2]; //===----------------------------------------------------------------------===// #endif diff --git a/test/SemaTemplate/instantiate-declref-ice.cpp b/test/SemaTemplate/instantiate-declref-ice.cpp index 0f3c08b056..49b1b63f51 100644 --- a/test/SemaTemplate/instantiate-declref-ice.cpp +++ b/test/SemaTemplate/instantiate-declref-ice.cpp @@ -31,4 +31,4 @@ struct X1 { template const unsigned X1::value = sizeof(T); -int array3[X1::value == sizeof(int)? 1 : -1]; // expected-error{{variable length array declaration not allowed at file scope}} +int array3[X1::value == sizeof(int)? 1 : -1];