Hi,
this patch fixes problems with weakref and LTO on non-weakref configurations.  
Here
the weakrefs are transparently removed by GCC via somewhat weird machinery.
DECL_ASSEMLBLER name gets flag IDENTIFIER_TRANSPARENT_ALIAS and the TREE_CHAIN 
makes assembler output routies to output instead of specified assembler name
different assembler name (weakref target).

This completely breaks with LTO that does not preserve TREE_CHAIN of 
IDENTIFIER_NODE
and also it breaks with symbol renaming - when weakref is renamed, we lose the
link, when target is renamed we are screwed up.

This patch makes the links to be set up only before final assembler output. 
Hopefully
it will solve the problem.

Jakub, Alexandre. Is there some reason why we can't simply rewrite GIMPLE 
bodies to contains
the weakref target decls in this case? (and also in the case both weakref and 
its target
is used)

In any case this is quite self contained fix that is backportable to 4.8 if 
needed.

Honza

2013-06-01  Jan Hubicka  <j...@suse.cz>

        PR middle-end/57366
        * cgraphunit.c (compile): When weakref is not supported,
        set up transparent aliases before final output pass.
        * varasm.c (assemble_alias): Do not try to do it here.


Index: cgraphunit.c
===================================================================
--- cgraphunit.c        (revision 199577)
+++ cgraphunit.c        (working copy)
@@ -1996,6 +1996,32 @@ compile (void)
   bitmap_obstack_release (NULL);
   mark_functions_to_output ();
 
+  /* When weakref support is missing, we autmatically translate all
+     references to NODE to references to its ultimate alias target.
+     The renaming mechanizm uses flag IDENTIFIER_TRANSPARENT_ALIAS and
+     TREE_CHAIN.
+
+     Set up this mapping before we output any assembler but once we are sure
+     that all symbol renaming is done.
+
+     FIXME: All this uglyness can go away if we just do renaming at gimple
+     level by physically rewritting the IL.  At the moment we can only redirect
+     calls, so we need infrastructure for renaming references as well.  */
+#ifndef ASM_OUTPUT_WEAKREF
+  symtab_node node;
+
+  FOR_EACH_SYMBOL (node)
+    if (node->symbol.alias
+       && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
+      {
+       IDENTIFIER_TRANSPARENT_ALIAS
+          (DECL_ASSEMBLER_NAME (node->symbol.decl)) = 1;
+       TREE_CHAIN (DECL_ASSEMBLER_NAME (node->symbol.decl))
+          = (node->symbol.alias_target ? node->symbol.alias_target
+             : DECL_ASSEMBLER_NAME (symtab_alias_target (node)->symbol.decl));
+      }
+#endif
+
   cgraph_state = CGRAPH_STATE_EXPANSION;
   if (!flag_toplevel_reorder)
     output_in_order ();
Index: varasm.c
===================================================================
--- varasm.c    (revision 199576)
+++ varasm.c    (working copy)
@@ -5560,13 +5560,6 @@ assemble_alias (tree decl, tree target)
 
       if (alias == target)
        error ("weakref %q+D ultimately targets itself", decl);
-      else
-       {
-#ifndef ASM_OUTPUT_WEAKREF
-         IDENTIFIER_TRANSPARENT_ALIAS (alias) = 1;
-         TREE_CHAIN (alias) = target;
-#endif
-       }
       if (TREE_PUBLIC (decl))
        error ("weakref %q+D must have static linkage", decl);
     }

Reply via email to