This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Do not output references from external vtables into LTO symbol table

this patch fixes GCC side of PR 56557 where we fail to link

#include <fstream>

int main()
  std::fstream x;

with -flto -rdynamic because we do not see definition of
_ZTCSt13basic_fstreamIcSt11char_traitsIcEE0_Sd.  This symbol mistakely appears
in lto symbol table because it is used from external constructor that is kept
around only for optimization.  There is also BFD linker bug that create stale
dynamic table entries for these kind of symbols.

Bootstrapped&regtested x86_64-linux, tested on Mozilla and Qt LTO build, comitted.


	PR lto/56557
	* lto-streamer-out.c (output_symbol_p): Skip references from
	constructors of external variables.
Index: lto-streamer-out.c
--- lto-streamer-out.c	(revision 196611)
+++ lto-streamer-out.c	(working copy)
@@ -1265,17 +1265,36 @@ bool
 output_symbol_p (symtab_node node)
   struct cgraph_node *cnode;
-  struct ipa_ref *ref;
   if (!symtab_real_symbol_p (node))
     return false;
   /* We keep external functions in symtab for sake of inlining
      and devirtualization.  We do not want to see them in symbol table as
-     references.  */
+     references unless they are really used.  */
   cnode = dyn_cast <cgraph_node> (node);
-  if (cnode && DECL_EXTERNAL (cnode->symbol.decl))
-    return (cnode->callers
-	    || ipa_ref_list_referring_iterate (&cnode->symbol.ref_list, 0, ref));
+  if (cnode && DECL_EXTERNAL (cnode->symbol.decl)
+      && cnode->callers)
+    return true;
+ /* Ignore all references from external vars initializers - they are not really
+    part of the compilation unit until they are used by folding.  Some symbols,
+    like references to external construction vtables can not be referred to at all.
+    We decide this at can_refer_decl_in_current_unit_p.  */
+ if (DECL_EXTERNAL (node->symbol.decl))
+    {
+      int i;
+      struct ipa_ref *ref;
+      for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
+					          i, ref); i++)
+	{
+	  if (ref->use == IPA_REF_ALIAS)
+	    continue;
+          if (is_a <cgraph_node> (ref->referring))
+	    return true;
+	  if (!DECL_EXTERNAL (ref->referring->symbol.decl))
+	    return true;
+	}
+      return false;
+    }
   return true;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]