Message ID | 20140320162554.GL19304@virgil.suse |
---|---|
State | New |
Headers | show |
On Thu, 20 Mar 2014, Martin Jambor wrote: > Hi, > > in PR 60419 we end up with a call graph node for a thunk that has no > callee because symtab_remove_unreachable_nodes has determined its body > is not needed although its declaration is still reachable (more > details in comment 11 in bugzilla) and removal of callees is a part of > the zombification process that such nodes undergo. Later on, the last > stage of inlining that runs after that connects the thunk to the call > graph and we segfault because we expect thunks to have a callee. > > So we can either keep thunk targets alive or clear the thunk flag. > Thunks and aliases are quite similar and > symtab_remove_unreachable_nodes does clear the alias flag and the "in > border" nodes are referred to but not output and thus just another > symbol. Therefore I believe it is correct and much simpler to remove > the thunk flag s well. > > Bootstrapped and tested on x86_64, I have also build Mozilla Firefox > witht the patch (without LTO, partly on purpose, partly because again > I'm having issues with LTO after updating FF). OK for trunk? Ok. Thanks, Richard. > There is the same issue on the 4.8 branch, but the patch does not > apply, I'm in the process of preparing it. > > Thanks, > > Martin > > > 2014-03-20 Martin Jambor <mjambor@suse.cz> > > PR ipa/60419 > * ipa.c (symtab_remove_unreachable_nodes): Clear thunk flag of nodes > in the border. > > testsuite/ > * g++.dg/ipa/pr60419.C: New test. > > diff --git a/gcc/ipa.c b/gcc/ipa.c > index 572dba1..164de0d 100644 > --- a/gcc/ipa.c > +++ b/gcc/ipa.c > @@ -488,6 +488,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) > node->definition = false; > node->cpp_implicit_alias = false; > node->alias = false; > + node->thunk.thunk_p = false; > node->weakref = false; > if (!node->in_other_partition) > node->local.local = false; > diff --git a/gcc/testsuite/g++.dg/ipa/pr60419.C b/gcc/testsuite/g++.dg/ipa/pr60419.C > new file mode 100644 > index 0000000..84461f3 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/ipa/pr60419.C > @@ -0,0 +1,80 @@ > +// PR middle-end/60419 > +// { dg-do compile } > +// { dg-options "-O2" } > + > +struct C > +{ > +}; > + > +struct I : C > +{ > + I (); > +}; > + > +struct J > +{ > + void foo (); > + J (); > + virtual void foo (int &, int); > +}; > + > +template <class> > +struct D > +{ > + virtual void foo (I &) const; > + void bar () > + { > + I p; > + foo (p); > + } > +}; > + > +struct K : J, public D<int> > +{ > +}; > + > +struct F > +{ > + K *operator->(); > +}; > + > +struct N : public K > +{ > + void foo (int &, int); > + I n; > + void foo (I &) const {} > +}; > + > +struct L : J > +{ > + F l; > +}; > + > +struct M : F > +{ > + L *operator->(); > +}; > + > +struct G > +{ > + G (); > +}; > + > +M h; > + > +G::G () > +try > +{ > + N f; > + f.bar (); > + throw; > +} > +catch (int) > +{ > +} > + > +void > +baz () > +{ > + h->l->bar (); > +} > >
diff --git a/gcc/ipa.c b/gcc/ipa.c index 572dba1..164de0d 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -488,6 +488,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) node->definition = false; node->cpp_implicit_alias = false; node->alias = false; + node->thunk.thunk_p = false; node->weakref = false; if (!node->in_other_partition) node->local.local = false; diff --git a/gcc/testsuite/g++.dg/ipa/pr60419.C b/gcc/testsuite/g++.dg/ipa/pr60419.C new file mode 100644 index 0000000..84461f3 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr60419.C @@ -0,0 +1,80 @@ +// PR middle-end/60419 +// { dg-do compile } +// { dg-options "-O2" } + +struct C +{ +}; + +struct I : C +{ + I (); +}; + +struct J +{ + void foo (); + J (); + virtual void foo (int &, int); +}; + +template <class> +struct D +{ + virtual void foo (I &) const; + void bar () + { + I p; + foo (p); + } +}; + +struct K : J, public D<int> +{ +}; + +struct F +{ + K *operator->(); +}; + +struct N : public K +{ + void foo (int &, int); + I n; + void foo (I &) const {} +}; + +struct L : J +{ + F l; +}; + +struct M : F +{ + L *operator->(); +}; + +struct G +{ + G (); +}; + +M h; + +G::G () +try +{ + N f; + f.bar (); + throw; +} +catch (int) +{ +} + +void +baz () +{ + h->l->bar (); +}