https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102586
--- Comment #10 from Jakub Jelinek <jakub at gcc dot gnu.org> --- So, on struct C0 {}; struct C1 {}; struct C2 : C1, virtual C0 {}; struct C3 : virtual C2, C1 { virtual int foo () { return 1; } }; struct C6 { char c; }; struct C7 : virtual C6, virtual C3, C1 { virtual int foo () { return 4; } }; struct C8 : C7 { virtual int foo () { return 5; } }; __attribute__((noipa)) void foo (C8 *q) { __builtin_clear_padding (q); } C8 c8; C7 c7; void bar () { c8.c = 42; c7.c = 43; } distilled from the testcase in the patch, c8.c is at 9 bytes into c8, while c7.c is at 8 bytes into c7, so that is likely the reason why the code considers both byte at offset 8 and 9 as non-padding - the first FIELD_DECL in C8 is one with C7 type (32 byte long like C8) but the field size is 9 bytes, so that the __builtin_clear_padding code thinks the first 9 bytes are non-padding, virtual table pointer inside of C2, then empty type C1 at off 8, then C6 at off 8 with the c 1-byte field, then C3 at offset 16 with 9 byte size but all this is already outside of the size of FIELD_DECL with C7 type. But C8 has a FIELD_DECL with C6 type at off 9...