Fix LTO streaming ICE

Message ID 20180410063533.GA66214@kam.mff.cuni.cz
State New
Headers show
Series
  • Fix LTO streaming ICE
Related show

Commit Message

Jan Hubicka April 10, 2018, 6:35 a.m.
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.

Patch

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