On Thu, Nov 24, 2016 at 5:44 PM, Martin Jambor <mjam...@suse.cz> wrote: > 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?
Ok. Richard. > 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 >