https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102586
--- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Created attachment 52404 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52404&action=edit gcc12-pr102586.patch With this WIP patch which just ignores fields that partially overlap there is no ICE and the (in the new testcase renamed) C5 case looks correct to me, __builtin_clear_padding there clears on x86_64 8 bytes at offsets 8 and 24 into the 32-byte object, i.e. everything except for the 2 virtual table pointers. And the testcase verifies those virtual table pointers aren't cleared and so can be still dereferenced. But the C8 case which is derived from your smol case above looks weird. I'd expect (but need to look at the layout details yet) that the still 32-byte c8 object contains 2 virtual pointers and 1 byte c member and everything else is padding. But __builtin_clear_padding clears there 6 and 8 bytes instead of 15 bytes together.