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); }