Hi,
this patch prevent lto streaming ice where devirtualization pulls out symbol
that is never seen by free lang data becuase type inheritnace graph contains
types that are no longer reference by IL.
Patch also fixes binfo walking - we need to walk vtables and there is no need
to walk virtuals becuase they are set to NULL these days.

Bootstrapped/regtested x86_64-linux and also tested with Firefox, comitted.

        PR lto/85078
        * ipa-devirt.c (rebuild_type_inheritance_graph): New.
        * ipa-utils.h (rebuild_type_inheritance_graph): Declare.
        * tree.c (free_lang_data_in_type): Fix handling of binfos;
        walk basetypes.
        (free_lang_data): Rebuild type inheritance graph.
        * g++.dg/torture/pr85078.C: New.
Index: ipa-devirt.c
===================================================================
--- ipa-devirt.c        (revision 259167)
+++ ipa-devirt.c        (working copy)
@@ -2702,6 +2702,24 @@
     }
 }
 
+/* Force rebuilding type inheritance graph from scratch.
+   This is use to make sure that we do not keep references to types
+   which was not visible to free_lang_data.  */
+
+void
+rebuild_type_inheritance_graph ()
+{
+  if (!odr_hash)
+    return;
+  delete odr_hash;
+  if (in_lto_p)
+    delete odr_vtable_hash;
+  odr_hash = NULL;
+  odr_vtable_hash = NULL;
+  odr_types_ptr = NULL;
+  free_polymorphic_call_targets_hash ();
+}
+
 /* When virtual function is removed, we may need to flush the cache.  */
 
 static void
Index: ipa-utils.h
===================================================================
--- ipa-utils.h (revision 259167)
+++ ipa-utils.h (working copy)
@@ -55,6 +55,7 @@
 struct odr_type_d;
 typedef odr_type_d *odr_type;
 void build_type_inheritance_graph (void);
+void rebuild_type_inheritance_graph (void);
 void update_type_inheritance_graph (void);
 vec <cgraph_node *>
 possible_polymorphic_call_targets (tree, HOST_WIDE_INT,
Index: testsuite/g++.dg/torture/pr85078.C
===================================================================
--- testsuite/g++.dg/torture/pr85078.C  (nonexistent)
+++ testsuite/g++.dg/torture/pr85078.C  (working copy)
@@ -0,0 +1,40 @@
+typedef __builtin_va_list a;
+
+class b
+{
+public:
+  virtual void c (int, const char *, a &);
+  char d;
+  void m_fn2 ()
+  {
+    a a;
+    c (2, &d, a);
+  }
+};
+
+class e:b
+{
+  virtual void f ()
+  {
+  }
+  void c (int, const char *, a &);
+};
+
+class g
+{
+protected:
+  b h;
+};
+
+class i:g
+{
+  int j ();
+};
+
+int
+i::j ()
+{
+  h.m_fn2 ();
+  return 0;
+}
+
Index: tree.c
===================================================================
--- tree.c      (revision 259167)
+++ tree.c      (working copy)
@@ -5521,7 +5522,8 @@
          tree tem;
          FOR_EACH_VEC_ELT (*BINFO_BASE_BINFOS (TYPE_BINFO (t)), i, tem)
            fld_worklist_push (TREE_TYPE (tem), fld);
-         fld_worklist_push (BINFO_VIRTUALS (TYPE_BINFO (t)), fld);
+         fld_worklist_push (BINFO_TYPE (TYPE_BINFO (t)), fld);
+         fld_worklist_push (BINFO_VTABLE (TYPE_BINFO (t)), fld);
        }
       if (RECORD_OR_UNION_TYPE_P (t))
        {
@@ -5540,6 +5542,8 @@
              tem = TREE_CHAIN (tem);
            }
        }
+      if (FUNC_OR_METHOD_TYPE_P (t))
+       fld_worklist_push (TYPE_METHOD_BASETYPE (t), fld);
 
       fld_worklist_push (TYPE_STUB_DECL (t), fld);
       *ws = 0;
@@ -5859,6 +5863,8 @@
   /* Reset diagnostic machinery.  */
   tree_diagnostics_defaults (global_dc);
 
+  rebuild_type_inheritance_graph ();
+
   return 0;
 }
 

Reply via email to