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

Reply via email to