PR c++/24389
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 16 Oct 2005 23:17:53 +0000 (23:17 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 16 Oct 2005 23:17:53 +0000 (23:17 +0000)
* decl2.c (mark_used): Use uses_template_parms instead of
dependent_type_p.
* init.c (constant_value_1): Handle uninstantiated templates
specially.
* pt.c (instantiate_decl): Add sanity check.
PR c++/24389
* g++.dg/template/static21.C: New test.
* g++.dg/template/static21-a.cc: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@105474 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/decl2.c
gcc/cp/init.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/static21-a.cc [new file with mode: 0644]
gcc/testsuite/g++.dg/template/static21.C [new file with mode: 0644]

index 2896ce2..9305e16 100644 (file)
@@ -1,5 +1,14 @@
 2005-10-16  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/24389
+       * decl2.c (mark_used): Use uses_template_parms instead of
+       dependent_type_p.
+       * init.c (constant_value_1): Handle uninstantiated templates
+       specially.
+       * pt.c (instantiate_decl): Add sanity check.
+
+2005-10-16  Mark Mitchell  <mark@codesourcery.com>
+
        PR c++/22173
        * typeck.c (check_template_keyword): Fix thinko.
                
index 1e81283..70ca017 100644 (file)
@@ -3253,22 +3253,26 @@ mark_used (tree decl)
      DECL.  However, if DECL is a static data member initialized with
      a constant, we need the value right now because a reference to
      such a data member is not value-dependent.  */
-  if (processing_template_decl)
-    {
-      if (TREE_CODE (decl) == VAR_DECL
-         && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)
-         && DECL_CLASS_SCOPE_P (decl)
-         && !dependent_type_p (DECL_CONTEXT (decl)))
-       {
-         /* Pretend that we are not in a template so that the
-            initializer for the static data member will be full
-            simplified.  */
-         saved_processing_template_decl = processing_template_decl;
-         processing_template_decl = 0;
-       }
-      else
-       return;  
+  if (TREE_CODE (decl) == VAR_DECL
+      && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)
+      && DECL_CLASS_SCOPE_P (decl))
+    {
+      /* Don't try to instantiate members of dependent types.  We
+        cannot just use dependent_type_p here because this function
+        may be called from fold_non_dependent_expr, and then we may
+        see dependent types, even though processing_template_decl
+        will not be set.  */
+      if (CLASSTYPE_TEMPLATE_INFO ((DECL_CONTEXT (decl)))
+         && uses_template_parms (CLASSTYPE_TI_ARGS (DECL_CONTEXT (decl))))
+       return;
+      /* Pretend that we are not in a template, even if we are, so
+        that the static data member initializer will be processed.  */
+      saved_processing_template_decl = processing_template_decl;
+      processing_template_decl = 0;
     }
+  
+  if (processing_template_decl)
+    return;  
 
   if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl)
       && !TREE_ASM_WRITTEN (decl))
index 809b74f..44cfc44 100644 (file)
@@ -1576,16 +1576,27 @@ constant_value_1 (tree decl, bool integral_p)
                && CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl)))))
     {
       tree init;
-      /* If DECL is a static data member in a template class, we must
-        instantiate it here.  The initializer for the static data
-        member is not processed until needed; we need it now.  */ 
-      mark_used (decl);
-      init = DECL_INITIAL (decl);
-      /* If we are currently processing a template, the
-        initializer for a static data member may not be dependent,
-        but it is not folded until instantiation time.  */
-      if (init)
-       init = fold_non_dependent_expr (init);
+      /* Static data members in template classes may have
+        non-dependent initializers.  References to such non-static
+        data members are no value-dependent, so we must retrieve the
+        initializer here.  The DECL_INITIAL will have the right type,
+        but will not have been folded because that would prevent us
+        from performing all appropriate semantic checks at
+        instantiation time.  */
+      if (DECL_CLASS_SCOPE_P (decl)
+         && CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (decl))
+         && uses_template_parms (CLASSTYPE_TI_ARGS 
+                                 (DECL_CONTEXT (decl))))
+       init = fold_non_dependent_expr (DECL_INITIAL (decl));
+      else
+       {
+         /* If DECL is a static data member in a template
+            specialization, we must instantiate it here.  The
+            initializer for the static data member is not processed
+            until needed; we need it now.  */
+         mark_used (decl);
+         init = DECL_INITIAL (decl);
+       }
       if (!(init || init == error_mark_node)
          || !TREE_TYPE (init)
          || (integral_p
index 1ef5669..3de54a4 100644 (file)
@@ -11502,6 +11502,10 @@ instantiate_decl (tree d, int defer_ok,
   td = template_for_substitution (d);
   code_pattern = DECL_TEMPLATE_RESULT (td);
 
+  /* We should never be trying to instantiate a member of a class
+     template or partial specialization.  */ 
+  gcc_assert (d != code_pattern);
   if ((DECL_NAMESPACE_SCOPE_P (d) && !DECL_INITIALIZED_IN_CLASS_P (d))
       || DECL_TEMPLATE_SPECIALIZATION (td))
     /* In the case of a friend template whose definition is provided
index 034df78..373a797 100644 (file)
@@ -1,3 +1,9 @@
+2005-10-16  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/24389
+       * g++.dg/template/static21.C: New test.
+       * g++.dg/template/static21-a.cc: Likewise.
+
 2005-10-16  Andrew Pinski  <pinskia@physics.uc.edu>
 
        PR c++/23959
diff --git a/gcc/testsuite/g++.dg/template/static21-a.cc b/gcc/testsuite/g++.dg/template/static21-a.cc
new file mode 100644 (file)
index 0000000..9489ae7
--- /dev/null
@@ -0,0 +1,17 @@
+template<int dummy>
+    struct X
+    {
+      static const int n_primes = 256;
+      static const unsigned long primes[n_primes + 1];
+    };
+
+  template<int dummy>
+  const int X<dummy>::n_primes;
+
+  template<int dummy>
+  const unsigned long X<dummy>::primes[n_primes + 1] =
+    { 0 };
+
+
+const unsigned long  *f1(void){return &X<0>::primes[0];}
+int main(){}
diff --git a/gcc/testsuite/g++.dg/template/static21.C b/gcc/testsuite/g++.dg/template/static21.C
new file mode 100644 (file)
index 0000000..66b0450
--- /dev/null
@@ -0,0 +1,20 @@
+// PR c++/24389
+// { dg-additional-sources "static21-a.cc" }
+// { dg-do link }
+
+template<int dummy>
+struct X
+{
+  static const int n_primes = 256;
+  static const unsigned long primes[n_primes + 1];
+};
+
+template<int dummy>
+const int X<dummy>::n_primes;
+
+template<int dummy>
+const unsigned long X<dummy>::primes[n_primes + 1] =
+  { 0 };
+
+const unsigned long  *f(void){return &X<0>::primes[0];}
+