This is the mail archive of the gcc-patches@gcc.gnu.org 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]

[PATCH, PR 58389] Do not attempt to use reference descriptions associated with removed edges


Hi,

PR 58389 is another case where the reference removal code, which is
now also called from the edge removal hook, ICEs when inlined edges
are not removed in topological order, which ins not the case when we
are removing unreachable nodes.

I'd like to fix it by the patch below.  When removing an edge which
has a reference descriptor pointing back to it, we set that pointer to
NULL and check for non-NULLness when we want to use it.  Reference
descriptors die only when their allocation pool does so that pointer
is never stale.

Bootstrapped and tested on x86_64-linux, OK for trunk?

Thanks,

Martin


2013-09-11  Martin Jambor  <mjambor@suse.cz>

	PR ipa/58389
	* ipa-prop.c (remove_described_reference): Give up if the edge in the
	reference descriptor is NULL.
	(ipa_edge_removal_hook): If owning a reference descriptor, set its
	edge to NULL.

testsuite/
	* g++.dg/pr58389.C: New test.

Index: src/gcc/ipa-prop.c
===================================================================
--- src.orig/gcc/ipa-prop.c
+++ src/gcc/ipa-prop.c
@@ -2506,6 +2506,8 @@ remove_described_reference (symtab_node
   struct cgraph_edge *origin;
 
   origin = rdesc->cs;
+  if (!origin)
+    return false;
   to_del = ipa_find_reference ((symtab_node) origin->caller, symbol,
 			       origin->call_stmt, origin->lto_stmt_uid);
   if (!to_del)
@@ -3019,7 +3021,14 @@ ipa_edge_removal_hook (struct cgraph_edg
       struct ipa_jump_func *jf;
       int i;
       FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
-	try_decrement_rdesc_refcount (jf);
+	{
+	  struct ipa_cst_ref_desc *rdesc;
+	  try_decrement_rdesc_refcount (jf);
+	  if (jf->type == IPA_JF_CONST
+	      && (rdesc = ipa_get_jf_constant_rdesc (jf))
+	      && rdesc->cs == cs)
+	    rdesc->cs = NULL;
+	}
     }
 
   ipa_free_edge_args_substructures (IPA_EDGE_REF (cs));
Index: src/gcc/testsuite/g++.dg/pr58389.C
===================================================================
--- /dev/null
+++ src/gcc/testsuite/g++.dg/pr58389.C
@@ -0,0 +1,54 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+template <typename _RandomAccessIterator, typename _Compare>
+void __insertion_sort(_RandomAccessIterator, _Compare);
+template <typename _RandomAccessIterator, typename _Compare>
+void __final_insertion_sort(_RandomAccessIterator p1, _Compare p2) {
+  _RandomAccessIterator a;
+  if (p1 - a)
+    ;
+  else
+  std:
+  __insertion_sort(0, p2);
+}
+template <typename _RandomAccessIterator, typename _Size, typename _Compare>
+void __introsort_loop(_RandomAccessIterator, _Size, _Compare);
+template <typename _RandomAccessIterator, typename _Compare>
+void sort(_RandomAccessIterator, _RandomAccessIterator p2, _Compare p3) {
+std:
+  __introsort_loop(0, 0, p3);
+  __final_insertion_sort(p2, p3);
+}
+class A {
+public:
+  int m_fn1();
+  void __lg();
+  class B {
+  public:
+    int i;
+    int operator-(B);
+  };
+};
+class C;
+class D {
+public:
+  C *operator->();
+};
+class F {
+  A m_fn1() const;
+  D d_ptr;
+};
+class C {
+  friend F;
+  void m_fn1();
+  A children;
+};
+void qt_notclosestLeaf();
+inline void C::m_fn1() {
+  A::B b, c;
+  if (children.m_fn1()) {
+    sort(c, b, qt_notclosestLeaf);
+  }
+}
+A F::m_fn1() const { const_cast<F *>(this)->d_ptr->m_fn1(); }


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