]> granicus.if.org Git - clang/commitdiff
If a static data member of a class template which could be used in a constant
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 15 Feb 2012 02:42:50 +0000 (02:42 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 15 Feb 2012 02:42:50 +0000 (02:42 +0000)
expression is referenced, defined, then referenced again, make sure we
instantiate it the second time it's referenced. This is the static data member
analogue of r150518.

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

lib/Sema/SemaExpr.cpp
test/SemaTemplate/constexpr-instantiate.cpp

index 050386e2995f2e04c80aebbfd91fc47363c60272..a11cba1bfbcd1e680960c424b2c03a7f16e3c86d 100644 (file)
@@ -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));
     }
   }
 
index 69ac0e476b5718408c8b402c67733ec6cb1992c5..316b0885664180e10f110157a13a30cc138b1eba 100644 (file)
@@ -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'}}
+}