]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/45699 (Incorrect copy constructor generated with -O)
authorMartin Jambor <mjambor@suse.cz>
Mon, 11 Oct 2010 18:45:23 +0000 (20:45 +0200)
committerMartin Jambor <jamborm@gcc.gnu.org>
Mon, 11 Oct 2010 18:45:23 +0000 (20:45 +0200)
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

gcc/ChangeLog
gcc/gimple-fold.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/otr-fold-1.C
gcc/testsuite/g++.dg/otr-fold-2.C
gcc/testsuite/g++.dg/torture/pr45699.C [new file with mode: 0644]

index a0743bd3dce888c9092f89dc59d5d77f732ef190..19016d348fe7d24fe24e81a0436a5cae7460968b 100644 (file)
@@ -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))
index d412eb2a74733a38941c0720a68a228f70e66b92..ce232e609e1fd2394e2c9e672f0574b359f1699f 100644 (file)
@@ -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
index d49e1ee45b71e23026c0811197cf16a266ecab3b..8d6d09f5ab6e813f72902ffa178922f09f11d20e 100644 (file)
@@ -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.
index cff5d072a9c562b0b82f6aeb2a859ba29335474f..2364730487e6109068c871e45fc195c163e8c8c1 100644 (file)
@@ -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" } } */
index 04fbf41026821f7e949e319da14045dfacc3621e..a3cd1b5e66f2cef708dfcdd52ad51186e149da34 100644 (file)
@@ -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 (file)
index 0000000..828c1ef
--- /dev/null
@@ -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;
+}