From 79a18702006d53bc378affcd5dd6c8df7883b58f Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Mon, 15 Apr 2019 10:30:36 +0200 Subject: [PATCH] Reorganize cgraph_node::clone_of_p 2019-04-15 Martin Jambor PR ipa/pr89693 * cgraph.c (clone_of_p): Loop over clone chain for each step in the thunk chain. testsuite/ * g++.dg/ipa/pr89693.C: New test. From-SVN: r270364 --- gcc/ChangeLog | 6 +++++ gcc/cgraph.c | 30 +++++++++++++--------- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/g++.dg/ipa/pr89693.C | 52 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ipa/pr89693.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2946bec..e85c08c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-04-15 Martin Jambor + + PR ipa/pr89693 + * cgraph.c (clone_of_p): Loop over clone chain for each step in + the thunk chain. + 2019-04-15 Monk Chiang * config.gcc (nds32*-*-linux*): Set gcc_cv_initfini_array to yes. diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 49d80ad..b1b0b4c 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -2977,17 +2977,25 @@ cgraph_node::collect_callers (void) static bool clone_of_p (cgraph_node *node, cgraph_node *node2) { - bool skipped_thunk = false; node = node->ultimate_alias_target (); node2 = node2->ultimate_alias_target (); + if (node2->clone_of == node + || node2->former_clone_of == node->decl) + return true; + + if (!node->thunk.thunk_p && !node->former_thunk_p ()) + { + while (node2 && node->decl != node2->decl) + node2 = node2->clone_of; + return node2 != NULL; + } + /* There are no virtual clones of thunks so check former_clone_of or if we might have skipped thunks because this adjustments are no longer necessary. */ while (node->thunk.thunk_p || node->former_thunk_p ()) { - if (node2->former_clone_of == node->decl) - return true; if (!node->thunk.this_adjusting) return false; /* In case of instrumented expanded thunks, which can have multiple calls @@ -2996,23 +3004,21 @@ clone_of_p (cgraph_node *node, cgraph_node *node2) if (node->callees->next_callee) return true; node = node->callees->callee->ultimate_alias_target (); - skipped_thunk = true; - } - if (skipped_thunk) - { if (!node2->clone.args_to_skip || !bitmap_bit_p (node2->clone.args_to_skip, 0)) return false; if (node2->former_clone_of == node->decl) return true; - else if (!node2->clone_of) - return false; + + cgraph_node *n2 = node2; + while (n2 && node->decl != n2->decl) + n2 = n2->clone_of; + if (n2) + return true; } - while (node2 && node->decl != node2->decl) - node2 = node2->clone_of; - return node2 != NULL; + return false; } /* Verify edge count and frequency. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 877ecc4..66dcfc4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-04-15 Martin Jambor + + PR ipa/pr89693 + * g++.dg/ipa/pr89693.C: New test. + 2019-04-15 Dominique d'Humieres PR tree-optimization/90020 diff --git a/gcc/testsuite/g++.dg/ipa/pr89693.C b/gcc/testsuite/g++.dg/ipa/pr89693.C new file mode 100644 index 0000000..4ac83ee --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr89693.C @@ -0,0 +1,52 @@ +// Copyright (C) 2005 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 4 Apr 2005 +// Re-purposed to check for re-rurgesnce of PR 89693 in 2019. + +// { dg-do compile } +// { dg-options "-O3 -fno-ipa-icf-functions" } + +// Origin: yanliu@ca.ibm.com +// nathan@codesourcery.com + +struct A { + virtual void One (); +}; +struct B { + virtual B *Two (); + virtual B &Three (); +}; + +struct C : A, B +{ + virtual C *Two (); + virtual C &Three (); +}; +void A::One () {} +B *B::Two() {return this;} +B &B::Three() {return *this;} +C *C::Two () {return 0;} +C &C::Three () {return *(C *)0;} + +B *Foo (B *b) +{ + return b->Two (); +} + +B &Bar (B *b) +{ + return b->Three (); +} + +int main () +{ + C c; + + /* We should not adjust a null pointer. */ + if (Foo (&c)) + return 1; + /* But we should adjust a (bogus) null reference. */ + if (!&Bar (&c)) + return 2; + + return 0; +} -- 2.7.4