diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cgraph.c | 8 | ||||
-rw-r--r-- | gcc/ipa-inline-transform.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ipa/pr94856.C | 18 |
5 files changed, 38 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f8d9688..69ecd22 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2020-04-30 Martin Jambor <mjambor@suse.cz> + + PR ipa/94856 + * cgraph.c (clone_of_p): Also consider thunks whih had their bodies + saved by the inliner and thunks which had their call inlined. + * ipa-inline-transform.c (save_inline_function_body): Fill in + former_clone_of of new body holders. + 2020-04-30 Jakub Jelinek <jakub@redhat.com> * BASE-VER: Set to 11.0.0. diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 72d7cb5..2a9813d 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -3104,15 +3104,17 @@ clone_of_p (cgraph_node *node, cgraph_node *node2) return false; /* In case of instrumented expanded thunks, which can have multiple calls in them, we do not know how to continue and just have to be - optimistic. */ - if (node->callees->next_callee) + optimistic. The same applies if all calls have already been inlined + into the thunk. */ + if (!node->callees || node->callees->next_callee) return true; node = node->callees->callee->ultimate_alias_target (); if (!node2->clone.param_adjustments || node2->clone.param_adjustments->first_param_intact_p ()) return false; - if (node2->former_clone_of == node->decl) + if (node2->former_clone_of == node->decl + || node2->former_clone_of == node->former_clone_of) return true; cgraph_node *n2 = node2; diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c index be60bbc..e9e21cc 100644 --- a/gcc/ipa-inline-transform.c +++ b/gcc/ipa-inline-transform.c @@ -607,6 +607,8 @@ save_inline_function_body (struct cgraph_node *node) } } *ipa_saved_clone_sources->get_create (first_clone) = prev_body_holder; + first_clone->former_clone_of + = node->former_clone_of ? node->former_clone_of : node->decl; first_clone->clone_of = NULL; /* Now node in question has no clones. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7d5ae75..c602564 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-04-30 Martin Jambor <mjambor@suse.cz> + + PR ipa/94856 + * g++.dg/ipa/pr94856.C: New test. + 2020-04-30 Iain Sandoe <iain@sandoe.co.uk> PR c++/94886 diff --git a/gcc/testsuite/g++.dg/ipa/pr94856.C b/gcc/testsuite/g++.dg/ipa/pr94856.C new file mode 100644 index 0000000..5315c52 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr94856.C @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-tree-dse --param uninlined-function-insns=0 --param early-inlining-insns=3 -fgnu-tm " } */ + +class a { +public: + virtual ~a() {} +}; +class b { +public: + virtual void c(); +}; +class C : a, public b {}; +class d : C { + ~d(); + void c(); +}; +d::~d() { ((b *)this)->c(); } +void d::c() {} |