]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/9683 (bug in initialization chains for static const variables from template...
authorMark Mitchell <mark@codesourcery.com>
Wed, 26 Feb 2003 05:39:01 +0000 (05:39 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Wed, 26 Feb 2003 05:39:01 +0000 (05:39 +0000)
PR c++/9683
* decl2.c (prune_vars_needing_no_initialization): Do not throw
away initializations for DECL_EXTERNAL VAR_DECLs.
(finish_file): Adjust accordingly.
* pt.c (instantiate_decl): Do not defer VAR_DECLs.

PR c++/9683
* g++.dg/template/static3.C: New test.

From-SVN: r63455

gcc/cp/ChangeLog
gcc/cp/decl2.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/static3.C [new file with mode: 0644]

index 3f4c7f69f24fec092a7328a2d7f7899a329bae1c..caa078c36493fcdfbcca7b8cb0a8a43138b704d3 100644 (file)
@@ -1,3 +1,11 @@
+2003-02-25  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/9683
+       * decl2.c (prune_vars_needing_no_initialization): Do not throw
+       away initializations for DECL_EXTERNAL VAR_DECLs.
+       (finish_file): Adjust accordingly.
+       * pt.c (instantiate_decl): Do not defer VAR_DECLs.
+
 2003-02-24 Gabriel Dos Reis  <gdr@integrable-solutions.net>
 
       * decl.c (add_binding): Time TV_NAME_LOOKUP.
index ae174034c083650cca7fab85c8e0f067a4988c88..52170daff2fa57051089e3c55b3c96468129f6fd 100644 (file)
@@ -84,7 +84,7 @@ static void finish_static_initialization_or_destruction (tree);
 static void generate_ctor_or_dtor_function (bool, int);
 static int generate_ctor_and_dtor_functions_for_priority (splay_tree_node,
                                                           void *);
-static tree prune_vars_needing_no_initialization (tree);
+static tree prune_vars_needing_no_initialization (tree *);
 static void write_out_vars (tree);
 static void import_export_class (tree);
 static tree get_guard_bits (tree);
@@ -2400,21 +2400,23 @@ do_static_destruction (tree decl)
    i.e., the first variable should be initialized first.  */
 
 static tree
-prune_vars_needing_no_initialization (tree vars)
+prune_vars_needing_no_initialization (tree *vars)
 {
-  tree var;
-  tree result;
+  tree *var = vars;
+  tree result = NULL_TREE;
 
-  for (var = vars, result = NULL_TREE;
-       var;
-       var = TREE_CHAIN (var))
+  while (*var)
     {
-      tree decl = TREE_VALUE (var);
-      tree init = TREE_PURPOSE (var);
+      tree t = *var;
+      tree decl = TREE_VALUE (t);
+      tree init = TREE_PURPOSE (t);
 
       /* Deal gracefully with error.  */
       if (decl == error_mark_node)
-       continue;
+       {
+         var = &TREE_CHAIN (t);
+         continue;
+       }
 
       /* The only things that can be initialized are variables.  */
       my_friendly_assert (TREE_CODE (decl) == VAR_DECL, 19990420);
@@ -2422,17 +2424,25 @@ prune_vars_needing_no_initialization (tree vars)
       /* If this object is not defined, we don't need to do anything
         here.  */
       if (DECL_EXTERNAL (decl))
-       continue;
+       {
+         var = &TREE_CHAIN (t);
+         continue;
+       }
 
       /* Also, if the initializer already contains errors, we can bail
         out now.  */
       if (init && TREE_CODE (init) == TREE_LIST 
          && value_member (error_mark_node, init))
-       continue;
+       {
+         var = &TREE_CHAIN (t);
+         continue;
+       }
 
       /* This variable is going to need initialization and/or
         finalization, so we add it to the list.  */
-      result = tree_cons (init, decl, result);
+      *var = TREE_CHAIN (t);
+      TREE_CHAIN (t) = result;
+      result = t;
     }
 
   return result;
@@ -2625,8 +2635,7 @@ finish_file ()
         aggregates added during the initialization of these will be
         initialized in the correct order when we next come around the
         loop.  */
-      vars = prune_vars_needing_no_initialization (static_aggregates);
-      static_aggregates = NULL_TREE;
+      vars = prune_vars_needing_no_initialization (&static_aggregates);
 
       if (vars)
        {
index a5425f34b4ab7cc1a5df9af0196197ba31bafa72..9336d96c09d37ecdb90f7ce8b16f16d8f5bdc89a 100644 (file)
@@ -10647,6 +10647,14 @@ instantiate_decl (d, defer_ok)
   my_friendly_assert (TREE_CODE (d) == FUNCTION_DECL
                      || TREE_CODE (d) == VAR_DECL, 0);
 
+  /* Variables are never deferred; if instantiation is required, they
+     are instantiated right away.  That allows for better code in the
+     case that an expression refers to the value of the variable --
+     if the variable has a constant value the referring expression can
+     take advantage of that fact.  */
+  if (TREE_CODE (d) == VAR_DECL)
+    defer_ok = 0;
+
   /* Don't instantiate cloned functions.  Instead, instantiate the
      functions they cloned.  */
   if (TREE_CODE (d) == FUNCTION_DECL && DECL_CLONED_FUNCTION_P (d))
index 86887e8482d291ef3508171d0ed7d677381f5b82..12fce54444dbbc9da9fcb7b508bc1a3e15093c6a 100644 (file)
@@ -1,5 +1,8 @@
 2003-02-25  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/9683
+       * g++.dg/template/static3.C: New test.
+
        PR c++/9829
        * g++.dg/parse/namespace6.C: New test.
        
diff --git a/gcc/testsuite/g++.dg/template/static3.C b/gcc/testsuite/g++.dg/template/static3.C
new file mode 100644 (file)
index 0000000..65cf2c9
--- /dev/null
@@ -0,0 +1,25 @@
+template <class data> class foo
+{
+    public:
+       static const int a;
+       static const int b;
+       static const int c;
+       static const int d;
+};
+
+template <class data> const int foo<data>::a = 1;
+template <class data> const int foo<data>::b = a;
+template <class data> const int foo<data>::c = b;
+template <class data> const int foo<data>::d = c;
+
+typedef foo<int> fooInt;
+
+int main( void )
+{
+    fooInt *f;
+
+    f = new fooInt();
+
+    if (f->c != 1 || f->d != 1)
+      return 1;
+}