Hi,

after discussing this with Honza, we have decided that scheduling an
extra pass_rebuild_cgraph_edges after pass_fixup_cfg is the correct
way to keep the cgraph consistent with gimple IL when early IPA passes
need it, such as is the case with the testcase in PR 70965.

While needing an extra pass is never nice, this is a consequence of
splitting pass_build_ssa_passes out of early optimization passes so
that pass_chkp can be in between.

The patch below fices the ICE in PR 70965 and has passed bootstrap and
testing on x86_64-linux.  OK for trunk?

Thanks,

Martin


2016-11-24  Martin Jambor  <mjam...@suse.cz>

gcc/
        * passes.def (pass_build_ssa_passes): Add pass_rebuild_cgraph_edges.

gcc/testsuite/
        * g++.dg/pr70965.C: New test.
---
 gcc/passes.def                 |  1 +
 gcc/testsuite/g++.dg/pr70965.C | 21 +++++++++++++++++++++
 2 files changed, 22 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/pr70965.C

diff --git a/gcc/passes.def b/gcc/passes.def
index 85a5af0..5faf17f 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3.  If not see
   NEXT_PASS (pass_build_ssa_passes);
   PUSH_INSERT_PASSES_WITHIN (pass_build_ssa_passes)
       NEXT_PASS (pass_fixup_cfg);
+      NEXT_PASS (pass_rebuild_cgraph_edges);
       NEXT_PASS (pass_build_ssa);
       NEXT_PASS (pass_warn_nonnull_compare);
       NEXT_PASS (pass_ubsan);
diff --git a/gcc/testsuite/g++.dg/pr70965.C b/gcc/testsuite/g++.dg/pr70965.C
new file mode 100644
index 0000000..d8a2c35
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr70965.C
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -std=c++11" } */
+
+struct A {};
+struct B {};
+struct C { using p = int *; template <typename> using ra = A; };
+struct J : C { template <typename> struct K { typedef C::ra<int> o; }; };
+template <typename> struct D
+{
+  struct H : J::K<int>::o { H (J::p, A) : J::K<int>::o () {} };
+  H d;
+  D (const char *, const A &x = A ()) : d (0, x) {}
+};
+extern template class D<char>;
+enum L { M };
+struct F { virtual char *foo (); };
+template <class> struct I : B { static int foo (int) {} };
+struct G { typedef I<int> t; };
+void foo (int) { G::t::foo (0); }
+void bar (const D<char> &, const D<int> &, int, L);
+void baz () try { foo (0); } catch (F &e) { bar (e.foo (), "", 0, M); }
-- 
2.10.2

Reply via email to