openwrtv4/openwrt/toolchain/gcc/3.4.2/300-pr17976.patch

107 lines
3 KiB
Diff
Raw Normal View History

2005-01-16 11:43:02 +00:00
From: Mark Mitchell <mark@codesourcery.com>
Sender: gcc-patches-owner@gcc.gnu.org
To: gcc-patches@gcc.gnu.org
Subject: C++ PATCH: PR 17976
Date: Thu, 14 Oct 2004 21:24:41 -0700
This was a case where we generated multiple destructor calls for the
same global variable, in the (probably rare) situation that an
"extern" declaration followed the definition.
Tested on i686-pc-linux-gnu, applied on the mainline and on the 3.4
branch.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
# DP: 2004-10-14 Mark Mitchell <mark@codesourcery.com>
# DP:
# DP: PR c++/17976
# DP: * decl.c (cp_finish_decl): Do not call expand_static_init more
# DP: than once for a single variable.
# DP:
# DP: 2004-10-14 Mark Mitchell <mark@codesourcery.com>
# DP:
# DP: PR c++/17976
# DP: * g++.dg/init/dtor3.C: New test.
Index: testsuite/g++.dg/init/dtor3.C
===================================================================
RCS file: testsuite/g++.dg/init/dtor3.C
diff -N testsuite/g++.dg/init/dtor3.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- gcc/gcc/testsuite/g++.dg/init/dtor3.C 15 Oct 2004 04:02:22 -0000
***************
*** 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;
+ }
+
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1174.2.26
retrieving revision 1.1174.2.27
diff -u -r1.1174.2.26 -r1.1174.2.27
--- gcc/gcc/cp/decl.c 2004/10/10 21:54:59 1.1174.2.26
+++ gcc/gcc/cp/decl.c 2004/10/15 04:23:46 1.1174.2.27
@@ -4778,6 +4778,7 @@
tree cleanup;
const char *asmspec = NULL;
int was_readonly = 0;
+ bool var_definition_p = false;
if (decl == error_mark_node)
return;
@@ -4930,6 +4931,11 @@
/* 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;
}
/* If the variable has an array type, lay out the type, even if
there is no initializer. It is valid to index through the
@@ -5004,8 +5010,16 @@
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);
}
finish_end0: