aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2019-04-15 10:30:36 +0200
committerMartin Jambor <jamborm@gcc.gnu.org>2019-04-15 10:30:36 +0200
commit79a18702006d53bc378affcd5dd6c8df7883b58f (patch)
tree85c9a79521fa8c8bcfe5fbf2005d6f2993a4e3fe /gcc
parent887e182f05d64c0cb2a888711d8d6ca1174fe93a (diff)
downloadgcc-79a18702006d53bc378affcd5dd6c8df7883b58f.zip
gcc-79a18702006d53bc378affcd5dd6c8df7883b58f.tar.gz
gcc-79a18702006d53bc378affcd5dd6c8df7883b58f.tar.bz2
Reorganize cgraph_node::clone_of_p
2019-04-15 Martin Jambor <mjambor@suse.cz> 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/cgraph.c30
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr89693.C52
4 files changed, 81 insertions, 12 deletions
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 <mjambor@suse.cz>
+
+ PR ipa/pr89693
+ * cgraph.c (clone_of_p): Loop over clone chain for each step in
+ the thunk chain.
+
2019-04-15 Monk Chiang <sh.chiang04@gmail.com>
* 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 <mjambor@suse.cz>
+
+ PR ipa/pr89693
+ * g++.dg/ipa/pr89693.C: New test.
+
2019-04-15 Dominique d'Humieres <dominiq@gcc.gnu.org>
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 <nathan@codesourcery.com>
+// 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;
+}