aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2010-10-11 20:45:23 +0200
committerMartin Jambor <jamborm@gcc.gnu.org>2010-10-11 20:45:23 +0200
commit3f1f0ae316e60e7d9c40e1fef5f24d92cd985a9a (patch)
tree8d6ed9719873c3ea29c68bb9687c7adf8babe3d8 /gcc
parent90a2689f4d6b68b7542b0f7b04d66fea1cee5c0f (diff)
downloadgcc-3f1f0ae316e60e7d9c40e1fef5f24d92cd985a9a.zip
gcc-3f1f0ae316e60e7d9c40e1fef5f24d92cd985a9a.tar.gz
gcc-3f1f0ae316e60e7d9c40e1fef5f24d92cd985a9a.tar.bz2
re PR middle-end/45699 (Incorrect copy constructor generated with -O)
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. From-SVN: r165327
Diffstat (limited to 'gcc')
-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 a0743bd..19016d3 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 d412eb2..ce232e6 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 d49e1ee..8d6d09f 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 cff5d07..2364730 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 04fbf41..a3cd1b5 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 0000000..828c1ef
--- /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;
+}