OSDN Git Service

PR c++/17976
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 15 Oct 2004 04:18:01 +0000 (04:18 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 15 Oct 2004 04:18:01 +0000 (04:18 +0000)
* decl.c (cp_finish_decl): Do not call expand_static_init more
than once for a single variable.

PR c++/17976
* g++.dg/init/dtor3.C: New test.

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

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/init/dtor3.C [new file with mode: 0644]

index bb8678e..8ae05c0 100644 (file)
@@ -1,3 +1,9 @@
+2004-10-14  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/17976
+       * decl.c (cp_finish_decl): Do not call expand_static_init more
+       than once for a single variable.
+
 2004-10-14  Matt Austern  <austern@apple.com>
 
        * Make-lang.in (pt.o): depends on pointer-set.h
index f077566..ee7e481 100644 (file)
@@ -4763,6 +4763,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
   tree cleanup;
   const char *asmspec = NULL;
   int was_readonly = 0;
+  bool var_definition_p = false;
 
   if (decl == error_mark_node)
     return;
@@ -4904,6 +4905,11 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
          /* Remember that the initialization for this variable has
             taken place.  */
          DECL_INITIALIZED_P (decl) = 1;
+         /* This declaration is the definition of this variable,
+            unless we are initializing a static data member within
+            the class specifier.  */
+         if (!DECL_EXTERNAL (decl))
+           var_definition_p = true;
          /* The variable is being defined, so determine its
             visibility.  */
          determine_visibility (decl);
@@ -4969,10 +4975,18 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
              else if (!TREE_STATIC (decl))
                initialize_local_var (decl, init);
            }
-
-         if (TREE_STATIC (decl))
-           expand_static_init (decl, init);
-       }
+         
+         /* If a variable is defined, and then a subsequent
+            definintion with external linkage is encountered, we will
+            get here twice for the same variable.  We want to avoid
+            calling expand_static_init more than once.  For variables
+            that are not static data members, we can call
+            expand_static_init only when we actually process the
+            initializer.  It is not legal to redeclare a static data
+            member, so this issue does not arise in that case.  */
+         if (var_definition_p && TREE_STATIC (decl))
+           expand_static_init (decl, init); 
+       } 
     }
 
   /* If a CLEANUP_STMT was created to destroy a temporary bound to a
index 5840d8e..1acfe77 100644 (file)
@@ -1,3 +1,8 @@
+2004-10-14  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/17976
+       * g++.dg/init/dtor3.C: New test.
+
 2004-10-15  Ben Elliston  <bje@au.ibm.com>
 
        * gcc.dg/ppc-stackalign-1.c: Set dg-options to {}.
diff --git a/gcc/testsuite/g++.dg/init/dtor3.C b/gcc/testsuite/g++.dg/init/dtor3.C
new file mode 100644 (file)
index 0000000..2af1ffe
--- /dev/null
@@ -0,0 +1,21 @@
+// PR c++/17976
+// { dg-do run }
+
+extern "C" void abort();
+struct A
+{
+  static int i;
+  A(){}
+  ~A(){i++;if(i>1)abort();}
+};
+
+int A::i = 0;
+
+A a;
+extern A a;
+
+int main()
+{
+  return 0;
+}
+