Initial revision
[openwrt.git] / 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