[cfe-commits] r150560 - in /cfe/trunk: lib/Sema/SemaExpr.cpp test/SemaTemplate/constexpr-instantiate.cpp

Richard Smith richard-llvm at metafoo.co.uk
Tue Feb 14 18:42:50 PST 2012


Author: rsmith
Date: Tue Feb 14 20:42:50 2012
New Revision: 150560

URL: http://llvm.org/viewvc/llvm-project?rev=150560&view=rev
Log:
If a static data member of a class template which could be used in a constant
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.

Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/SemaTemplate/constexpr-instantiate.cpp

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=150560&r1=150559&r2=150560&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Feb 14 20:42:50 2012
@@ -9988,22 +9988,26 @@
     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));
     }
   }
 

Modified: cfe/trunk/test/SemaTemplate/constexpr-instantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/constexpr-instantiate.cpp?rev=150560&r1=150559&r2=150560&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/constexpr-instantiate.cpp (original)
+++ cfe/trunk/test/SemaTemplate/constexpr-instantiate.cpp Tue Feb 14 20:42:50 2012
@@ -57,3 +57,11 @@
   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'}}
+}





More information about the cfe-commits mailing list