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
This commit is contained in:
Martin Jambor 2010-10-11 20:45:23 +02:00 committed by Martin Jambor
parent 90a2689f4d
commit 3f1f0ae316
6 changed files with 96 additions and 3 deletions

View 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))

View 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

View 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.

View 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" } } */

View 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" } } */

View File

@ -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;
}