]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/12909 (ambiguity in mangling vector types)
authorJason Merrill <jason@redhat.com>
Wed, 3 Mar 2010 19:01:58 +0000 (14:01 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 3 Mar 2010 19:01:58 +0000 (14:01 -0500)
PR c++/12909
* cgraph.h (varpool_node): Add extra_name field.
* varpool.c (varpool_extra_name_alias): New.
(varpool_assemble_decl): Emit extra name aliases.
(varpool_mark_needed_node): Look past an extra name alias.
cp/
* mangle.c (mangle_decl): Handle VAR_DECL, too.

From-SVN: r157203

gcc/ChangeLog
gcc/cgraph.h
gcc/cp/mangle.c
gcc/testsuite/g++.dg/abi/mangle40.C
gcc/varpool.c

index 5d1f34ddec78445d704357f8b1353e34f53eab40..1ae9f6710513eda97a1d08ed468614dbc37d453d 100644 (file)
@@ -1,3 +1,11 @@
+2010-03-03  Jason Merrill  <jason@redhat.com>
+
+       PR c++/12909
+       * cgraph.h (varpool_node): Add extra_name field.
+       * varpool.c (varpool_extra_name_alias): New.
+       (varpool_assemble_decl): Emit extra name aliases.
+       (varpool_mark_needed_node): Look past an extra name alias.
+
 2010-03-03  Eric Botcazou  <ebotcazou@adacore.com>
 
        * config.gcc (sparc64-*-solaris2*, sparc-*-solaris2*): Merge into...
index 802b28038d9eb2023194a658435ac68495b2ae02..f8d52ebc5601a951f5e0c205aa192c3a48319f8c 100644 (file)
@@ -361,6 +361,9 @@ struct GTY((chain_next ("%h.next"))) varpool_node {
   struct varpool_node *next;
   /* Pointer to the next function in varpool_nodes_queue.  */
   struct varpool_node *next_needed;
+  /* For normal nodes a pointer to the first extra name alias.  For alias
+     nodes a pointer to the normal node.  */
+  struct varpool_node *extra_name;
   /* Ordering of all cgraph nodes.  */
   int order;
 
@@ -379,7 +382,8 @@ struct GTY((chain_next ("%h.next"))) varpool_node {
   unsigned output : 1;
   /* Set when function is visible by other units.  */
   unsigned externally_visible : 1;
-  /* Set for aliases once they got through assemble_alias.  */
+  /* Set for aliases once they got through assemble_alias.  Also set for
+     extra name aliases in varpool_extra_name_alias.  */
   unsigned alias : 1;
 };
 
@@ -574,6 +578,7 @@ bool varpool_assemble_decl (struct varpool_node *node);
 bool varpool_analyze_pending_decls (void);
 void varpool_remove_unreferenced_decls (void);
 void varpool_empty_needed_queue (void);
+bool varpool_extra_name_alias (tree, tree);
 const char * varpool_node_name (struct varpool_node *node);
 
 /* Walk all reachable static variables.  */
index 02b8a82c26be886ac649188dd36e3b64de57f869..3bcefbbdb95a3c995352f47608f29b85739ad517 100644 (file)
@@ -3070,9 +3070,6 @@ mangle_decl (const tree decl)
        inform (DECL_SOURCE_LOCATION (decl), "-fabi-version=4 (or =0) "
                "avoids this error with a change in vector mangling");
 
-      if (TREE_CODE (decl) != FUNCTION_DECL)
-       return;
-
       save_ver = flag_abi_version;
       flag_abi_version = 0;
       id2 = mangle_decl_string (decl);
@@ -3085,7 +3082,10 @@ mangle_decl (const tree decl)
       DECL_VISIBILITY (alias) = DECL_VISIBILITY (decl);
       if (vague_linkage_p (decl))
        DECL_WEAK (alias) = 1;
-      cgraph_same_body_alias (alias, decl);
+      if (TREE_CODE (decl) == FUNCTION_DECL)
+       cgraph_same_body_alias (alias, decl);
+      else
+       varpool_extra_name_alias (alias, decl);
     }
 #endif
 }
index 1d604ef162dc9b22e00a58a67466362a8c10a13e..d73d94383b8ee36d0136dbbf0f107c43dd539b61 100644 (file)
@@ -3,6 +3,7 @@
 // { dg-options "-mavx -Wabi -fabi-version=2" }
 // { dg-final { scan-assembler "weak\[^\n\]*_Z1fIDv4_fEvT_" } }
 // { dg-final { scan-assembler "weak\[^\n\]*_Z1fIU8__vectorfEvT_" } }
+// { dg-final { scan-assembler "weak\[^\n\]*_ZN1AIDv4_fE1tE" } }
 // { dg-final { scan-assembler "weak\[^\n\]*_ZN1AIU8__vectorfE1tE" } }
 
 #include <x86intrin.h>
index 157755b195e1ef126c8fbf064a99c43397017fdf..121086e9c97bc7e1ca7a7e85edd77041915ce911 100644 (file)
@@ -207,6 +207,8 @@ varpool_enqueue_needed_node (struct varpool_node *node)
 void
 varpool_mark_needed_node (struct varpool_node *node)
 {
+  if (node->alias && node->extra_name)
+    node = node->extra_name;
   if (!node->needed && node->finalized
       && !TREE_ASM_WRITTEN (node->decl))
     varpool_enqueue_needed_node (node);
@@ -383,9 +385,22 @@ varpool_assemble_decl (struct varpool_node *node)
       assemble_variable (decl, 0, 1, 0);
       if (TREE_ASM_WRITTEN (decl))
        {
+         struct varpool_node *alias;
+
          node->next_needed = varpool_assembled_nodes_queue;
          varpool_assembled_nodes_queue = node;
          node->finalized = 1;
+
+         /* Also emit any extra name aliases.  */
+         for (alias = node->extra_name; alias; alias = alias->next)
+           {
+             /* Update linkage fields in case they've changed.  */
+             DECL_WEAK (alias->decl) = DECL_WEAK (decl);
+             TREE_PUBLIC (alias->decl) = TREE_PUBLIC (decl);
+             DECL_VISIBILITY (alias->decl) = DECL_VISIBILITY (decl);
+             assemble_alias (alias->decl, DECL_ASSEMBLER_NAME (decl));
+           }
+
          return true;
        }
     }
@@ -507,4 +522,40 @@ add_new_static_var (tree type)
   return new_node->decl;
 }
 
+/* Attempt to mark ALIAS as an alias to DECL.  Return TRUE if successful.
+   Extra name aliases are output whenever DECL is output.  */
+
+bool
+varpool_extra_name_alias (tree alias, tree decl)
+{
+  struct varpool_node key, *alias_node, *decl_node, **slot;
+
+#ifndef ASM_OUTPUT_DEF
+  /* If aliases aren't supported by the assembler, fail.  */
+  return false;
+#endif
+
+  gcc_assert (TREE_CODE (decl) == VAR_DECL);
+  gcc_assert (TREE_CODE (alias) == VAR_DECL);
+  /* Make sure the hash table has been created.  */
+  decl_node = varpool_node (decl);
+
+  key.decl = alias;
+
+  slot = (struct varpool_node **) htab_find_slot (varpool_hash, &key, INSERT);
+
+  /* If the varpool_node has been already created, fail.  */
+  if (*slot)
+    return false;
+
+  alias_node = GGC_CNEW (struct varpool_node);
+  alias_node->decl = alias;
+  alias_node->alias = 1;
+  alias_node->extra_name = decl_node;
+  alias_node->next = decl_node->extra_name;
+  decl_node->extra_name = alias_node;
+  *slot = alias_node;
+  return true;
+}
+
 #include "gt-varpool.h"