Initial revision
[openwrt/staging/dedeckeh.git] / openwrt / toolchain / gcc / 3.4.2 / 300-pr17976.patch
1 From: Mark Mitchell <mark@codesourcery.com>
2 Sender: gcc-patches-owner@gcc.gnu.org
3 To: gcc-patches@gcc.gnu.org
4 Subject: C++ PATCH: PR 17976
5 Date: Thu, 14 Oct 2004 21:24:41 -0700
6
7
8 This was a case where we generated multiple destructor calls for the
9 same global variable, in the (probably rare) situation that an
10 "extern" declaration followed the definition.
11
12 Tested on i686-pc-linux-gnu, applied on the mainline and on the 3.4
13 branch.
14
15 --
16 Mark Mitchell
17 CodeSourcery, LLC
18 mark@codesourcery.com
19
20 # DP: 2004-10-14 Mark Mitchell <mark@codesourcery.com>
21 # DP:
22 # DP: PR c++/17976
23 # DP: * decl.c (cp_finish_decl): Do not call expand_static_init more
24 # DP: than once for a single variable.
25 # DP:
26 # DP: 2004-10-14 Mark Mitchell <mark@codesourcery.com>
27 # DP:
28 # DP: PR c++/17976
29 # DP: * g++.dg/init/dtor3.C: New test.
30
31 Index: testsuite/g++.dg/init/dtor3.C
32 ===================================================================
33 RCS file: testsuite/g++.dg/init/dtor3.C
34 diff -N testsuite/g++.dg/init/dtor3.C
35 *** /dev/null 1 Jan 1970 00:00:00 -0000
36 --- gcc/gcc/testsuite/g++.dg/init/dtor3.C 15 Oct 2004 04:02:22 -0000
37 ***************
38 *** 0 ****
39 --- 1,21 ----
40 + // PR c++/17976
41 + // { dg-do run }
42 +
43 + extern "C" void abort();
44 + struct A
45 + {
46 + static int i;
47 + A(){}
48 + ~A(){i++;if(i>1)abort();}
49 + };
50 +
51 + int A::i = 0;
52 +
53 + A a;
54 + extern A a;
55 +
56 + int main()
57 + {
58 + return 0;
59 + }
60 +
61 ===================================================================
62 RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
63 retrieving revision 1.1174.2.26
64 retrieving revision 1.1174.2.27
65 diff -u -r1.1174.2.26 -r1.1174.2.27
66 --- gcc/gcc/cp/decl.c 2004/10/10 21:54:59 1.1174.2.26
67 +++ gcc/gcc/cp/decl.c 2004/10/15 04:23:46 1.1174.2.27
68 @@ -4778,6 +4778,7 @@
69 tree cleanup;
70 const char *asmspec = NULL;
71 int was_readonly = 0;
72 + bool var_definition_p = false;
73
74 if (decl == error_mark_node)
75 return;
76 @@ -4930,6 +4931,11 @@
77 /* Remember that the initialization for this variable has
78 taken place. */
79 DECL_INITIALIZED_P (decl) = 1;
80 + /* This declaration is the definition of this variable,
81 + unless we are initializing a static data member within
82 + the class specifier. */
83 + if (!DECL_EXTERNAL (decl))
84 + var_definition_p = true;
85 }
86 /* If the variable has an array type, lay out the type, even if
87 there is no initializer. It is valid to index through the
88 @@ -5004,8 +5010,16 @@
89 initialize_local_var (decl, init);
90 }
91
92 - if (TREE_STATIC (decl))
93 - expand_static_init (decl, init);
94 + /* If a variable is defined, and then a subsequent
95 + definintion with external linkage is encountered, we will
96 + get here twice for the same variable. We want to avoid
97 + calling expand_static_init more than once. For variables
98 + that are not static data members, we can call
99 + expand_static_init only when we actually process the
100 + initializer. It is not legal to redeclare a static data
101 + member, so this issue does not arise in that case. */
102 + if (var_definition_p && TREE_STATIC (decl))
103 + expand_static_init (decl, init);
104 }
105 finish_end0:
106