diff options
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 24 | ||||
-rw-r--r-- | test/SemaTemplate/constexpr-instantiate.cpp | 8 |
2 files changed, 22 insertions, 10 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 050386e299..a11cba1bfb 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -9988,22 +9988,26 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc, return; // Implicit instantiation of static data members of class templates. - if (Var->isStaticDataMember() && - Var->getInstantiatedFromStaticDataMember()) { + if (Var->isStaticDataMember() && Var->getInstantiatedFromStaticDataMember()) { MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo(); assert(MSInfo && "Missing member specialization information?"); - if (MSInfo->getPointOfInstantiation().isInvalid() && - MSInfo->getTemplateSpecializationKind()== TSK_ImplicitInstantiation) { - MSInfo->setPointOfInstantiation(Loc); - // This is a modification of an existing AST node. Notify listeners. - if (ASTMutationListener *L = SemaRef.getASTMutationListener()) - L->StaticDataMemberInstantiated(Var); + bool AlreadyInstantiated = !MSInfo->getPointOfInstantiation().isInvalid(); + if (MSInfo->getTemplateSpecializationKind() == TSK_ImplicitInstantiation && + (!AlreadyInstantiated || Var->isUsableInConstantExpressions())) { + if (!AlreadyInstantiated) { + // This is a modification of an existing AST node. Notify listeners. + if (ASTMutationListener *L = SemaRef.getASTMutationListener()) + L->StaticDataMemberInstantiated(Var); + MSInfo->setPointOfInstantiation(Loc); + } + SourceLocation PointOfInstantiation = MSInfo->getPointOfInstantiation(); if (Var->isUsableInConstantExpressions()) // Do not defer instantiations of variables which could be used in a // constant expression. - SemaRef.InstantiateStaticDataMemberDefinition(Loc, Var); + SemaRef.InstantiateStaticDataMemberDefinition(PointOfInstantiation,Var); else - SemaRef.PendingInstantiations.push_back(std::make_pair(Var, Loc)); + SemaRef.PendingInstantiations.push_back( + std::make_pair(Var, PointOfInstantiation)); } } diff --git a/test/SemaTemplate/constexpr-instantiate.cpp b/test/SemaTemplate/constexpr-instantiate.cpp index 69ac0e476b..316b088566 100644 --- a/test/SemaTemplate/constexpr-instantiate.cpp +++ b/test/SemaTemplate/constexpr-instantiate.cpp @@ -57,3 +57,11 @@ namespace OverloadResolution { S<4> &k = g(0); int *p, *q = h(p); } + +namespace DataMember { + template<typename T> struct S { static const int k; }; + const int n = S<int>::k; // expected-note {{here}} + template<typename T> const int S<T>::k = 0; + constexpr int m = S<int>::k; // ok + constexpr int o = n; // expected-error {{constant expression}} expected-note {{initializer of 'n'}} +} |