https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102586
--- Comment #26 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Though, I must say I don't understand how that works currently at all.
For say
struct C0 {};
struct C1 {};
struct C2 : C1, virtual C0 {};
struct C3 : virtual C2, C1 {};
struct C6 { char c; };
struct C7 : virtual C6, virtual C3, C1 {};
struct C8 : C7 {};
void bar (C8 *);
void
foo ()
{
C8 c;
bar (&c);
}
I see in gimple dump:
c = .DEFERRED_INIT (32, 1, &"c"[0]);
__builtin_clear_padding (&c, 0B, 1);
C8::C8 (&c);
bar (&c);
and it does something only because C8::C8 doesn't get the -flifetime-dse=2
CLOBBER at the start.
But if I do:
struct C { char a; int b; char c; long d; C () : a (42), b (42), c (42), d (42)
{} };
void bar (C *);
void
foo ()
{
C c;
bar (&c);
}
then *.gimple is:
c = .DEFERRED_INIT (24, 1, &"c"[0]);
__builtin_clear_padding (&c, 0B, 1);
C::C (&c);
bar (&c);
...
void C::C (struct C * const this)
{
*this = {CLOBBER};
{
this->a = 42;
this->b = 42;
this->c = 42;
this->d = 42;
}
}
After einline this is:
c = .DEFERRED_INIT (24, 1, &"c"[0]);
MEM <char[3]> [(struct C *)&c + 1B] = {};
MEM <char[7]> [(struct C *)&c + 9B] = {};
c ={v} {CLOBBER};
c.a = 42;
c.b = 42;
c.c = 42;
c.d = 42;
bar (&c);
and that keeps until dse1 which optimizes that out:
c ={v} {CLOBBER};
c.a = 42;
c.b = 42;
c.c = 42;
c.d = 42;
bar (&c);
so there is no zero padding initialization at all.