This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PATCH: PR c++/39188: G++ doesn't handle static anonymous union right
On Thu, Feb 19, 2009 at 12:33:25AM -0500, Jason Merrill wrote:
> H.J. Lu wrote:
>> DECL_NAME (anon_union_decl) = DECL_NAME (main_decl);
>> mangle_decl (anon_union_decl);
>> DECL_NAME (anon_union_decl) = NULL_TREE;
>
> Ah, of course--I read the first line and then stopped.
>
> But I don't think we can get that far into assemble_variable for a
> variable with no assembler name; I think it's better to just remove the
> DECL_NAME check rather than add a DECL_ASSEMBLER_NAME check which will
> always be true.
>
Here is the updated patch with the DECL_NAME check removed. OK for
trunk if no regressions on Linux/ia32, Linux/ia64 and Linux/x86-64?
Thanks.
H.J.
----
gcc/
2009-02-15 H.J. Lu <hongjiu.lu@intel.com>
PR c++/39188
* varasm.c (assemble_variable): Don't check DECL_NAME when
globalizing a variable.
gcc/cp/
2009-02-15 H.J. Lu <hongjiu.lu@intel.com>
PR c++/39188
* cp-tree.h (maybe_commonize_var): New.
* decl.c (maybe_commonize_var): Make it extern.
* decl2.c (finish_anon_union): Call maybe_commonize_var.
gcc/testsuite/
2009-02-15 H.J. Lu <hongjiu.lu@intel.com>
PR c++/39188
* g++.dg/abi/pr39188-1a.C: New.
* g++.dg/abi/pr39188-1b.C: Likewise.
* g++.dg/abi/pr39188-1.h: Likewise.
* g++.dg/abi/pr39188-2a.C: Likewise.
* g++.dg/abi/pr39188-2b.C: Likewise.
* g++.dg/abi/pr39188-2.h: Likewise.
* g++.dg/abi/pr39188-3a.C: Likewise.
* g++.dg/abi/pr39188-3b.C: Likewise.
* g++.dg/abi/pr39188-3.h: Likewise.
--- gcc/cp/cp-tree.h.pr39188 2009-02-14 06:42:19.000000000 -0800
+++ gcc/cp/cp-tree.h 2009-02-18 11:30:11.000000000 -0800
@@ -4360,6 +4360,7 @@ extern tree finish_function (int);
extern tree start_method (cp_decl_specifier_seq *, const cp_declarator *, tree);
extern tree finish_method (tree);
extern void maybe_register_incomplete_var (tree);
+extern void maybe_commonize_var (tree);
extern void complete_vars (tree);
extern void finish_stmt (void);
extern void print_other_binding_stack (struct cp_binding_level *);
--- gcc/cp/decl.c.pr39188 2009-01-22 09:43:12.000000000 -0800
+++ gcc/cp/decl.c 2009-02-18 11:30:11.000000000 -0800
@@ -81,7 +81,6 @@ static tree lookup_and_check_tag (enum t
static int walk_namespaces_r (tree, walk_namespaces_fn, void *);
static void maybe_deduce_size_from_array_init (tree, tree);
static void layout_var_decl (tree);
-static void maybe_commonize_var (tree);
static tree check_initializer (tree, tree, int, tree *);
static void make_rtl_for_nonlocal_decl (tree, tree, const char *);
static void save_function_data (tree);
@@ -4536,7 +4535,7 @@ layout_var_decl (tree decl)
we have a weak definition, we must endeavor to create only one
instance of the variable at link-time. */
-static void
+void
maybe_commonize_var (tree decl)
{
/* Static data in a function with comdat linkage also has comdat
--- gcc/cp/decl2.c.pr39188 2009-02-12 08:35:45.000000000 -0800
+++ gcc/cp/decl2.c 2009-02-18 11:30:11.000000000 -0800
@@ -1364,6 +1364,7 @@ finish_anon_union (tree anon_union_decl)
{
/* Use main_decl to set the mangled name. */
DECL_NAME (anon_union_decl) = DECL_NAME (main_decl);
+ maybe_commonize_var (anon_union_decl);
mangle_decl (anon_union_decl);
DECL_NAME (anon_union_decl) = NULL_TREE;
}
--- gcc/testsuite/g++.dg/abi/pr39188-1.h.pr39188 2009-02-18 11:30:11.000000000 -0800
+++ gcc/testsuite/g++.dg/abi/pr39188-1.h 2009-02-18 11:30:11.000000000 -0800
@@ -0,0 +1,11 @@
+inline int
+f (int x)
+{
+ static union
+ {
+ int i;
+ };
+ int j = i;
+ i = x;
+ return j;
+}
--- gcc/testsuite/g++.dg/abi/pr39188-1a.C.pr39188 2009-02-18 11:30:11.000000000 -0800
+++ gcc/testsuite/g++.dg/abi/pr39188-1a.C 2009-02-18 11:30:11.000000000 -0800
@@ -0,0 +1,12 @@
+// PR c++/39188
+// { dg-do run }
+// { dg-options "-O2" }
+// { dg-additional-sources "pr39188-1b.C" }
+
+#include "pr39188-1.h"
+
+int
+x (int i)
+{
+ return f (i);
+}
--- gcc/testsuite/g++.dg/abi/pr39188-1b.C.pr39188 2009-02-18 11:30:11.000000000 -0800
+++ gcc/testsuite/g++.dg/abi/pr39188-1b.C 2009-02-18 11:30:11.000000000 -0800
@@ -0,0 +1,15 @@
+#include "pr39188-1.h"
+
+extern "C" void abort ();
+
+extern int x (int);
+
+int
+main (void)
+{
+ if (x (1) != 0)
+ abort ();
+ if (f (1) != 1)
+ abort ();
+ return 0;
+}
--- gcc/testsuite/g++.dg/abi/pr39188-2.h.pr39188 2009-02-18 11:30:11.000000000 -0800
+++ gcc/testsuite/g++.dg/abi/pr39188-2.h 2009-02-18 11:30:11.000000000 -0800
@@ -0,0 +1,12 @@
+template<typename T>
+T
+f (T x)
+{
+ static union
+ {
+ T i;
+ };
+ T j = i;
+ i = x;
+ return j;
+}
--- gcc/testsuite/g++.dg/abi/pr39188-2a.C.pr39188 2009-02-18 11:30:11.000000000 -0800
+++ gcc/testsuite/g++.dg/abi/pr39188-2a.C 2009-02-18 11:30:11.000000000 -0800
@@ -0,0 +1,12 @@
+// PR c++/39188
+// { dg-do run }
+// { dg-options "-O2" }
+// { dg-additional-sources "pr39188-2b.C" }
+
+#include "pr39188-2.h"
+
+int
+x (int i)
+{
+ return f<int> (i);
+}
--- gcc/testsuite/g++.dg/abi/pr39188-2b.C.pr39188 2009-02-18 11:30:11.000000000 -0800
+++ gcc/testsuite/g++.dg/abi/pr39188-2b.C 2009-02-18 11:30:11.000000000 -0800
@@ -0,0 +1,15 @@
+#include "pr39188-2.h"
+
+extern "C" void abort ();
+
+extern int x (int);
+
+int
+main (void)
+{
+ if (x (1) != 0)
+ abort ();
+ if (f<int> (1) != 1)
+ abort ();
+ return 0;
+}
--- gcc/testsuite/g++.dg/abi/pr39188-3.h.pr39188 2009-02-18 11:30:11.000000000 -0800
+++ gcc/testsuite/g++.dg/abi/pr39188-3.h 2009-02-18 11:30:11.000000000 -0800
@@ -0,0 +1,11 @@
+static int
+f (int x)
+{
+ static union
+ {
+ int i;
+ };
+ int j = i;
+ i = x;
+ return j;
+}
--- gcc/testsuite/g++.dg/abi/pr39188-3a.C.pr39188 2009-02-18 11:30:11.000000000 -0800
+++ gcc/testsuite/g++.dg/abi/pr39188-3a.C 2009-02-18 11:30:11.000000000 -0800
@@ -0,0 +1,12 @@
+// PR c++/39188
+// { dg-do run }
+// { dg-options "-O2" }
+// { dg-additional-sources "pr39188-3b.C" }
+
+#include "pr39188-3.h"
+
+int
+x (int i)
+{
+ return f (i);
+}
--- gcc/testsuite/g++.dg/abi/pr39188-3b.C.pr39188 2009-02-18 11:30:11.000000000 -0800
+++ gcc/testsuite/g++.dg/abi/pr39188-3b.C 2009-02-18 11:30:11.000000000 -0800
@@ -0,0 +1,15 @@
+#include "pr39188-3.h"
+
+extern "C" void abort ();
+
+extern int x (int);
+
+int
+main (void)
+{
+ if (x (1) != 0)
+ abort ();
+ if (f (1) != 0)
+ abort ();
+ return 0;
+}
--- gcc/varasm.c.pr39188 2008-11-30 08:52:29.000000000 -0800
+++ gcc/varasm.c 2009-02-18 21:52:37.000000000 -0800
@@ -2161,7 +2161,6 @@ assemble_variable (tree decl, int top_le
/* First make the assembler name(s) global if appropriate. */
sect = get_variable_section (decl, false);
if (TREE_PUBLIC (decl)
- && DECL_NAME (decl)
&& (sect->common.flags & SECTION_COMMON) == 0)
globalize_decl (decl);