Hi, this patch fixes linker error seen during LTO build of libmerged. Linker complains that symbol resolved to dynamic library is hidden and therefore should be defined locally.
The bug is already in LTO symbol table that calls binds_local_p and uses hidden visibility on those symbols and in this case binds_local_p returns true on the external definition that is a bug. The patch also fixes problem in lto-cgraph where we can end up with both definition and body_removed flags that is a nonsense and adds checking to symtab.c lto-bootstrapped/regtested x86_64-linux and tested on libreoffice build. Honza * symtab.c (symtab_node::verify_base): Verify body_removed->!definiton * lto-cgraph.c (lto_output_varpool_node): Do not keep definition of variables in boundary that have no inlitalizer encoded and are not aliases. * varasm.c (default_binds_local_p_2): External definitions do not count as definitions here. Index: symtab.c =================================================================== --- symtab.c (revision 220741) +++ symtab.c (working copy) @@ -978,6 +978,11 @@ symtab_node::verify_base (void) error ("double linked list of assembler names corrupted"); error_found = true; } + if (body_removed && definition) + { + error ("node has body_removed but is definition"); + error_found = true; + } if (analyzed && !definition) { error ("node is analyzed byt it is not a definition"); Index: lto-cgraph.c =================================================================== --- lto-cgraph.c (revision 220741) +++ lto-cgraph.c (working copy) @@ -608,12 +608,18 @@ lto_output_varpool_node (struct lto_simp lto_symtab_encoder_t encoder) { bool boundary_p = !lto_symtab_encoder_in_partition_p (encoder, node); + bool encode_initializer_p + = (node->definition + && lto_symtab_encoder_encode_initializer_p (encoder, node)); struct bitpack_d bp; int ref; const char *comdat; const char *section; tree group; + gcc_assert (!encode_initializer_p || node->definition); + gcc_assert (boundary_p || encode_initializer_p); + streamer_write_enum (ob->main_stream, LTO_symtab_tags, LTO_symtab_last_tag, LTO_symtab_variable); streamer_write_hwi_stream (ob->main_stream, node->order); @@ -624,11 +630,14 @@ lto_output_varpool_node (struct lto_simp bp_pack_value (&bp, node->force_output, 1); bp_pack_value (&bp, node->forced_by_abi, 1); bp_pack_value (&bp, node->unique_name, 1); - bp_pack_value (&bp, node->body_removed - || !lto_symtab_encoder_encode_initializer_p (encoder, node), 1); + bp_pack_value (&bp, + node->body_removed + || (!encode_initializer_p && !node->alias && node->definition), + 1); bp_pack_value (&bp, node->implicit_section, 1); bp_pack_value (&bp, node->writeonly, 1); - bp_pack_value (&bp, node->definition, 1); + bp_pack_value (&bp, node->definition && (encode_initializer_p || node->alias), + 1); bp_pack_value (&bp, node->alias, 1); bp_pack_value (&bp, node->weakref, 1); bp_pack_value (&bp, node->analyzed && !boundary_p, 1); Index: varasm.c =================================================================== --- varasm.c (revision 220741) +++ varasm.c (working copy) @@ -6831,7 +6831,8 @@ default_binds_local_p_2 (const_tree exp, bool defined_locally = false; if (symtab_node *node = symtab_node::get (exp)) { - if (node->definition || node->in_other_partition) + if ((node->definition && !DECL_EXTERNAL (node->decl)) + || node->in_other_partition) { defined_locally = true; resolved_locally = (weak_dominate && !shlib);