From 5bf31c642ec176701629edc19504b79be3c12ee5 Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Tue, 17 Apr 2018 10:48:41 +0200 Subject: [PATCH] Call expand_all_artificial_thunks in ipa-cp if necessary 2018-04-17 Martin Jambor PR ipa/85421 * ipa-cp.c (create_specialized_node): Call expand_all_artificial_thunks if necessary. testsuite/ * g++.dg/ipa/pr85421.C: New test. From-SVN: r259432 --- gcc/ChangeLog | 6 ++ gcc/ipa-cp.c | 3 + gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/g++.dg/ipa/pr85421.C | 131 +++++++++++++++++++++++++++++ 4 files changed, 145 insertions(+) create mode 100644 gcc/testsuite/g++.dg/ipa/pr85421.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 186665e5b51..21966a39d8e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-04-17 Martin Jambor + + PR ipa/85421 + * ipa-cp.c (create_specialized_node): Call + expand_all_artificial_thunks if necessary. + 2018-04-17 Martin Liska PR lto/85405 diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index b2627ffd05f..4e0e20af409 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -3863,6 +3863,7 @@ create_specialized_node (struct cgraph_node *node, new_node = node->create_virtual_clone (callers, replace_trees, args_to_skip, "constprop"); + bool have_self_recursive_calls = !self_recursive_calls.is_empty (); for (unsigned j = 0; j < self_recursive_calls.length (); j++) { cgraph_edge *cs = next_edge_clone[self_recursive_calls[j]->uid]; @@ -3870,6 +3871,8 @@ create_specialized_node (struct cgraph_node *node, gcc_assert (cs->caller == new_node); cs->redirect_callee_duplicating_thunks (new_node); } + if (have_self_recursive_calls) + new_node->expand_all_artificial_thunks (); ipa_set_node_agg_value_chain (new_node, aggvals); for (av = aggvals; av; av = av->next) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d1d15605cfa..9e44409cb7a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-04-17 Martin Jambor + + PR ipa/85421 + * g++.dg/ipa/pr85421.C: New test. + 2018-04-17 Martin Liska PR lto/85405 diff --git a/gcc/testsuite/g++.dg/ipa/pr85421.C b/gcc/testsuite/g++.dg/ipa/pr85421.C new file mode 100644 index 00000000000..517d99ae8f4 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr85421.C @@ -0,0 +1,131 @@ +// { dg-do compile } +// { dg-options "-O3 -std=gnu++1y -w" } + +namespace { +template b c(b); +template class> struct f { + using g = d; +}; +template class aa> using h = f; +template class aa> +using i = typename h::g; +template struct j { typedef b k; }; +} // namespace +namespace l { +template class m { +public: + typedef b k; +}; +} // namespace l +namespace a { +template using n = l::m; +template class ac : public n {}; +struct s { + template using ad = typename b::e; +}; +template struct p : s { + typedef typename o::k k; + using ag = i; +}; +} // namespace a +namespace l { +template struct t : a::p {}; +} // namespace l +namespace a { +template struct al { + template static void an(am ao, am) { c(*ao); } +}; +template void aq(am ao, am ap) { + typedef typename j::k ar; + al<__has_trivial_destructor(ar)>::an(ao, ap); +} +namespace { +typedef char au; +} +} // namespace a +typedef char av; +typedef int aw; +typedef av ay; +typedef aw az; +namespace a { +template struct ba { + typedef typename l::t::ag ag; + struct { + ag bb; + ag bc; + } bd; +}; +template > class be : ba { + typedef ba bf; + typedef typename bf::ag ag; + +public: + void bh() { bi(this->bd.bb); } + void bi(ag bj) { aq(bj, this->bd.bc); } +}; +} // namespace a +namespace bk { +enum bl {}; +enum bn { bo }; +class q { +public: + static a::au bp(bn); + static bool bq(a::au *br, bn g) { return bs(br, g); } + static bl bs(a::au *br, bn g) { + if (br) { + auto bt = bp(g); + if (bt) + return bl(); + } + } +}; +template class bu {}; +} // namespace bk +namespace bv { +namespace bw { +class bx; +} +} // namespace bv +namespace bk { +enum by { bz }; +struct ca; +class cb { +public: + class cc { + public: + virtual void cd(by) = 0; + }; + virtual bu e(); + cc *cf; +}; +class cg { +public: + ~cg() { q::bq(ch, bo); } + a::au *ch; +}; +class ci { + cg cj; +}; +namespace ck { +enum cl : ay; +} +class r : ci {}; +class cn { +public: + ck::cl co(); +}; +by cp(ck::cl); +class cq : cb, cb::cc { + bu ce(bv::bw::bx &, az) noexcept; + void cd(by); + void cr(bv::bw::bx &, az, cb::cc *) noexcept; + cn cs; + a::be ct; +}; +} // namespace bk +using bv::bw::bx; +namespace bk { +bu cq::ce(bx &, az) noexcept { ct.bh(); } +void cq::cr(bx &, az, cb::cc *) noexcept { cd(bz); } +void cq::cd(by) { cf->cd(cp(cs.co())); } +} // namespace bk -- 2.30.2