Hi, On Fri, Mar 21, 2014 at 09:41:24AM +0100, Richard Biener wrote: > 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, I have just committed the trunk patch. A proposed 4.8 variant is below, it does the same thing at the same spot, although there is a number of minor differences between the branches. One of them is that symtab_remove_unreachable_nodes does not clear any flags there in 4.8 and therefore I have added also clearing of the alias flag because (although I do not have a testcase) just like there should not be any thunks without callees, there also should not be any aliases without references, cgraph_function_node would choke on them too. Bootstrapped and tested on the 4.8 branch on x86_64-linux. OK for the branch? Thanks, Martin 2014-03-20 Martin Jambor <mjam...@suse.cz> PR ipa/60419 * ipa.c (symtab_remove_unreachable_nodes): Clear thunk and alias flags of nodes in the border. testsuite/ * g++.dg/ipa/pr60419.C: New test. diff --git a/gcc/ipa.c b/gcc/ipa.c index a9b8fb4..d73d105 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -359,6 +359,8 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) { if (file) fprintf (file, " %s", cgraph_node_name (node)); + node->alias = false; + node->thunk.thunk_p = false; cgraph_node_remove_callees (node); ipa_remove_all_references (&node->symbol.ref_list); changed = true; 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 (); +}