------- Comment #2 from jakub at gcc dot gnu dot org 2009-06-09 17:11 -------
Confirmed. Shorter testcase:
template <typename V> struct S
{
V *f, *l;
__attribute__ ((noinline)) S (void) { f = 0, l = 0; }
void foo (V *x)
{
if (x->p != 0)
x->p->n = x->n;
else
f = x->n;
if (x->n != 0)
x->n->p = x->p;
else
l = x->p;
}
__attribute__ ((noinline)) void bar (V *x)
{
x->n = 0;
x->p = l;
if (l != 0)
l->n = x;
else
f = x;
l = x;
}
};
struct H;
struct A
{
S <H> k;
};
struct H
{
A *a;
H *p, *n;
__attribute__ ((noinline)) H (void) { p = 0, n = 0, a = 0; }
__attribute__ ((noinline)) H (A *b) : a (b)
{
p = 0;
n = 0;
if (a != 0)
a->k.bar (this);
}
__attribute__ ((noinline)) H (const H &h) : a (h.a)
{
p = 0;
n = 0;
if (a != 0)
a->k.bar (this);
}
~H (void) { if (a != 0) a->k.foo (this); }
H &operator= (const H &o)
{
if (a != 0 || &o == this)
__builtin_abort ();
a = o.a;
if (a != 0)
a->k.bar (this);
return *this;
}
};
__attribute__ ((noinline))
H baz (void)
{
return H (new A);
}
H g;
int
main (void)
{
g = baz ();
if (g.a->k.f != &g)
__builtin_abort ();
return 0;
}
doesn't fail with -O -fno-tree-sra, fails with -O. I've added a few noinline
attributes to make the debugging easier. Seems values from baz returned object
are cached in local variables across the bar call which modifies them. Likely
gcc doesn't consider this object as having address taken, even when it is
returned by invisible reference.
--
jakub at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
Ever Confirmed|0 |1
Last reconfirmed|0000-00-00 00:00:00 |2009-06-09 17:11:13
date| |
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40389