2015-02-09 Martin Liska * ipa-icf.c (sem_item_optimizer::register_hooks): Register hooks just if not yet registered. (ipa_icf_generate_summary): Register callgraph hooks. * g++.dg/ipa/pr64858.C: New test. --- gcc/ipa-icf.c (revision 220530) +++ gcc/ipa-icf.c (revision 220531) @@ -1562,11 +1562,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); - - m_varpool_node_hooks = symtab->add_varpool_removal_hook - (&sem_item_optimizer::varpool_removal_hook, this); + if (!m_cgraph_node_hooks) + m_cgraph_node_hooks = symtab->add_cgraph_removal_hook + (&sem_item_optimizer::cgraph_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. */ @@ -2438,6 +2440,7 @@ ipa_icf_generate_summary (void) if (!optimizer) optimizer = new sem_item_optimizer (); + optimizer->register_hooks (); optimizer->parse_funcs_and_vars (); } --- gcc/testsuite/g++.dg/ipa/pr64858.C (revision 0) +++ gcc/testsuite/g++.dg/ipa/pr64858.C (revision 220531) @@ -0,0 +1,93 @@ +// { dg-do compile } +// { dg-options "-O2 -std=gnu++11" } + +template class A +{ + reference_type *m_pBody; +public: + A (const A &) { m_pBody->acquire (); } +}; +class B; +class C +{ +protected: + B *_pInterface; +}; +template class I : C +{ +public: + I (interface_type *); +}; +class B +{ +public: + virtual void acquire (); +}; +class D +{ +protected: + void acquire (); +}; +template class J : D, public Ifc1 +{ + void + acquire () + { + D::acquire (); + } +}; +class K : B +{ +}; +class L; +class F +{ + A m_pDocument; + F (A const &, int &&); +}; +class XUnoTunnel; +class XEventTarget; +template class WeakImplHelper3 : D, B +{ + void + acquire () + { + D::acquire (); + } +}; +template class G +{ +public: + void + acquire () + { + WeakImplHelper3 (); + } +}; +struct H +{ + H () + : mxAttribList (new J), mxCurrentHandler (0), mxDocHandler (0), + mxTokenHandler (0) + { + } + I > mxAttribList; + I mxCurrentHandler; + I mxDocHandler; + I mxTokenHandler; +}; +class L : public G +{ +}; +class M : public J +{ +public: + M (); +}; +template I::I (interface_type *p1) +{ + B *a = static_cast (static_cast (p1)); + _pInterface = a; + _pInterface->acquire (); +} +F::F (A const &p1, int &&) : m_pDocument (p1) { I (new M); }