Hi. Attached patch handles situation where remove_unreachable_nodes is called before IPA ICF registers removal hooks. As a result, a deleted callgraph node is touched.
Tested on x86_64-linux-pc without a new regression seen. Ready for trunk? Thanks, Martin
>From 3be6518536de93b9e5397a4f65cb7e07422efbbb Mon Sep 17 00:00:00 2001 From: mliska <mli...@suse.cz> Date: Fri, 30 Jan 2015 12:25:22 +0100 Subject: [PATCH] IPA ICF: Fix late initialization of callgraph hooks. gcc/testsuite/ChangeLog: 2015-01-30 Martin Liska <mli...@suse.cz> * g++.dg/ipa/pr64858.C: New test. gcc/ChangeLog: 2015-01-30 Martin Liska <mli...@suse.cz> * ipa-icf.c (sem_item_optimizer::register_hooks): Register hooks just if not yet registered. (ipa_icf_generate_summary): Register callgraph hooks. --- gcc/ipa-icf.c | 11 +++-- gcc/testsuite/g++.dg/ipa/pr64858.C | 93 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ipa/pr64858.C diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c index afb5be5..544304f 100644 --- a/gcc/ipa-icf.c +++ b/gcc/ipa-icf.c @@ -1550,11 +1550,13 @@ sem_item_optimizer::read_summary (void) void sem_item_optimizer::register_hooks (void) { - m_cgraph_node_hooks = symtab->add_cgraph_removal_hook - (&sem_item_optimizer::cgraph_removal_hook, this); + if (!m_cgraph_node_hooks) + m_cgraph_node_hooks = symtab->add_cgraph_removal_hook + (&sem_item_optimizer::cgraph_removal_hook, this); - m_varpool_node_hooks = symtab->add_varpool_removal_hook - (&sem_item_optimizer::varpool_removal_hook, this); + if (!m_varpool_node_hooks) + m_varpool_node_hooks = symtab->add_varpool_removal_hook + (&sem_item_optimizer::varpool_removal_hook, this); } /* Unregister callgraph and varpool hooks. */ @@ -2426,6 +2428,7 @@ ipa_icf_generate_summary (void) if (!optimizer) optimizer = new sem_item_optimizer (); + optimizer->register_hooks (); optimizer->parse_funcs_and_vars (); } diff --git a/gcc/testsuite/g++.dg/ipa/pr64858.C b/gcc/testsuite/g++.dg/ipa/pr64858.C new file mode 100644 index 0000000..c03feaf --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr64858.C @@ -0,0 +1,93 @@ +// { dg-do compile } +// { dg-options "-O2 -std=gnu++11" } + +template <class reference_type> class A +{ + reference_type *m_pBody; +public: + A (const A &) { m_pBody->acquire (); } +}; +class B; +class C +{ +protected: + B *_pInterface; +}; +template <class interface_type> class I : C +{ +public: + I (interface_type *); +}; +class B +{ +public: + virtual void acquire (); +}; +class D +{ +protected: + void acquire (); +}; +template <class Ifc1> class J : D, public Ifc1 +{ + void + acquire () + { + D::acquire (); + } +}; +class K : B +{ +}; +class L; +class F +{ + A<L> m_pDocument; + F (A<L> const &, int &&); +}; +class XUnoTunnel; +class XEventTarget; +template <class, class> class WeakImplHelper3 : D, B +{ + void + acquire () + { + D::acquire (); + } +}; +template <class> class G +{ +public: + void + acquire () + { + WeakImplHelper3<XUnoTunnel, XEventTarget> (); + } +}; +struct H +{ + H () + : mxAttribList (new J<B>), mxCurrentHandler (0), mxDocHandler (0), + mxTokenHandler (0) + { + } + I<J<B> > mxAttribList; + I<int> mxCurrentHandler; + I<int> mxDocHandler; + I<int> mxTokenHandler; +}; +class L : public G<int> +{ +}; +class M : public J<K> +{ +public: + M (); +}; +template <class interface_type> I<interface_type>::I (interface_type *p1) +{ + B *a = static_cast<B *> (static_cast<void *> (p1)); + _pInterface = a; + _pInterface->acquire (); +} +F::F (A<L> const &p1, int &&) : m_pDocument (p1) { I<K> (new M); } -- 2.1.2