https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103839
Bug ID: 103839 Summary: __builtin_clear_padding doesn't zero alignment holes of unions with fields that overlap padding Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: ibuclaw at gdcproject dot org Target Milestone: --- Consider: --- // { dg-additional-options "-ftrivial-auto-var-init=zero" } union U { struct { char a; int b; } c; int d; }; int main() { U u[2] = {{1, 2}, {3, 4}}; } --- Because of `int d`, the three byte padding that would be required to fill the gap between the two struct fields is ignored. So after gimple lowering, we are left with: --- u[0].c.a = 1; u[0].c.b = 2; u[1].c.a = 3; u[1].c.b = 4; GIMPLE_NOP --- Instead of the expected: --- u[0].c.a = 1; u[0].c.b = 2; u[1].c.a = 3; u[1].c.b = 4; MEM <char[3]> [(union U[2] *)&a + 1B] = {}; MEM <char[3]> [(union U[2] *)&a + 9B] = {}; --- And inspecting the data in gdb, we visibly have garbage in the object. --- (gdb) p u $1 = {{c = {a = 1 '\001', b = 2}, d = 1025}, {c = {a = 3 '\003', b = 4}, d = 4355}} --- I can work around this by setting DECL_PADDING_P on all fields in unions except the first. However I suspect this is a mistake, and the proper thing to do would be to only consider the first field when clear padding a union.