aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/cgraph.c8
-rw-r--r--gcc/ipa-inline-transform.c2
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr94856.C18
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() {}