summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>2010-10-11 18:45:23 +0000
committerjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>2010-10-11 18:45:23 +0000
commitbf2335d79e11e01a00c785213dd5653e7520126e (patch)
tree8d6ed9719873c3ea29c68bb9687c7adf8babe3d8
parent86bde516ba3d5ab62218fffd4ac88e416eafb569 (diff)
downloadppe42-gcc-bf2335d79e11e01a00c785213dd5653e7520126e.tar.gz
ppe42-gcc-bf2335d79e11e01a00c785213dd5653e7520126e.zip
2010-10-11 Martin Jambor <mjambor@suse.cz>
PR middle-end/45699 * gimple-fold.c (gimple_fold_obj_type_ref_known_binfo): Choose among thunks. * testsuite/g++.dg/torture/pr45699.C: New test. * testsuite/g++.dg/otr-fold-1.C: Adjusted. * testsuite/g++.dg/otr-fold-1.C: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@165327 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/gimple-fold.c21
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/otr-fold-1.C2
-rw-r--r--gcc/testsuite/g++.dg/otr-fold-2.C2
-rw-r--r--gcc/testsuite/g++.dg/torture/pr45699.C61
6 files changed, 96 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a0743bd3dce..19016d348fe 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2010-10-11 Martin Jambor <mjambor@suse.cz>
+
+ PR middle-end/45699
+ * gimple-fold.c (gimple_fold_obj_type_ref_known_binfo): Choose among
+ thunks.
+
2010-10-11 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* Makefile.in ($(lang_checks_parallel))
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index d412eb2a747..ce232e609e1 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -1463,7 +1463,7 @@ tree
gimple_fold_obj_type_ref_known_binfo (HOST_WIDE_INT token, tree known_binfo)
{
HOST_WIDE_INT i;
- tree v, fndecl;
+ tree v, fndecl, delta;
v = BINFO_VIRTUALS (known_binfo);
i = 0;
@@ -1475,6 +1475,25 @@ gimple_fold_obj_type_ref_known_binfo (HOST_WIDE_INT token, tree known_binfo)
}
fndecl = TREE_VALUE (v);
+ delta = TREE_PURPOSE (v);
+ gcc_assert (host_integerp (delta, 0));
+
+ if (integer_nonzerop (delta))
+ {
+ struct cgraph_node *node = cgraph_get_node (fndecl);
+ HOST_WIDE_INT off = tree_low_cst (delta, 0);
+
+ if (!node)
+ return NULL;
+ for (node = node->same_body; node; node = node->next)
+ if (node->thunk.thunk_p && off == node->thunk.fixed_offset)
+ break;
+ if (node)
+ fndecl = node->decl;
+ else
+ return NULL;
+ }
+
/* When cgraph node is missing and function is not public, we cannot
devirtualize. This can happen in WHOPR when the actual method
ends up in other partition, because we found devirtualization
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d49e1ee45b7..8d6d09f5ab6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2010-10-11 Martin Jambor <mjambor@suse.cz>
+
+ PR middle-end/45699
+ * g++.dg/torture/pr45699.C: New test.
+ * g++.dg/otr-fold-1.C: Adjusted.
+ * g++.dg/otr-fold-1.C: Likewise.
+
2010-10-11 Nick Clifton <nickc@redhat.com>
* gcc.c-torture/compile/pr44197.c: Require visibility support.
diff --git a/gcc/testsuite/g++.dg/otr-fold-1.C b/gcc/testsuite/g++.dg/otr-fold-1.C
index cff5d072a9c..2364730487e 100644
--- a/gcc/testsuite/g++.dg/otr-fold-1.C
+++ b/gcc/testsuite/g++.dg/otr-fold-1.C
@@ -72,5 +72,5 @@ int main (int argc, char *argv[])
return 0;
}
-/* { dg-final { scan-tree-dump "= B::foo" "optimized" } } */
+/* { dg-final { scan-tree-dump "= B::.*foo" "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/g++.dg/otr-fold-2.C b/gcc/testsuite/g++.dg/otr-fold-2.C
index 04fbf410268..a3cd1b5e66f 100644
--- a/gcc/testsuite/g++.dg/otr-fold-2.C
+++ b/gcc/testsuite/g++.dg/otr-fold-2.C
@@ -84,5 +84,5 @@ int main (int argc, char *argv[])
return 0;
}
-/* { dg-final { scan-tree-dump "= B::foo" "optimized" } } */
+/* { dg-final { scan-tree-dump "= B::.*foo" "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/g++.dg/torture/pr45699.C b/gcc/testsuite/g++.dg/torture/pr45699.C
new file mode 100644
index 00000000000..828c1ef8e57
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr45699.C
@@ -0,0 +1,61 @@
+// { dg-do run }
+
+extern "C" void abort ();
+
+class A
+{
+public:
+ virtual void foo () {abort();}
+};
+
+class B : public A
+{
+public:
+ int z;
+ virtual void foo () {abort();}
+};
+
+class C : public A
+{
+public:
+ void *a[32];
+ unsigned long b;
+ long c[32];
+
+ virtual void foo () {abort();}
+};
+
+class D : public C, public B
+{
+public:
+ D () : C(), B()
+ {
+ int i;
+ for (i = 0; i < 32; i++)
+ {
+ a[i] = (void *) 0;
+ c[i] = 0;
+ }
+ b = 0xaaaa;
+ }
+
+ virtual void foo ();
+};
+
+void D::foo()
+{
+ if (b != 0xaaaa)
+ abort();
+}
+
+static inline void bar (B &b)
+{
+ b.foo ();
+}
+
+int main()
+{
+ D d;
+ bar (d);
+ return 0;
+}
OpenPOWER on IntegriCloud