diff options
| author | Alex Kladov <aleksey.kladov@gmail.com> | 2023-06-28 01:44:02 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2023-06-28 16:36:32 +0200 |
| commit | 4620972d086ebb3b7686a79914876488c6dfd171 (patch) | |
| tree | 8f2f47f0a02deb0f535f77b38a801d0259ac1745 /src | |
| parent | 28f515acd7bb6e008fcb2e9f760053f0c9e97992 (diff) | |
| download | zig-4620972d086ebb3b7686a79914876488c6dfd171.tar.gz zig-4620972d086ebb3b7686a79914876488c6dfd171.zip | |
Sema: preserve extern struct field alignment
In
extern struct { x: u32, y: u16 }
we actually know that y's alignment is `@alignOf(u32)`, and not just
`@alignOf(u16)`.
closes: #16134
Diffstat (limited to 'src')
| -rw-r--r-- | src/Sema.zig | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index c1ec7d1f01..0681de4ad5 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -25926,9 +25926,13 @@ fn structFieldPtrByIndex( ptr_ty_data.packed_offset = .{ .host_size = 0, .bit_offset = 0 }; } } - } else if (struct_obj.layout == .Extern and field_index == 0) { - // This is the first field in memory, so can inherit the struct alignment - ptr_ty_data.flags.alignment = Alignment.fromByteUnits(parent_align); + } else if (struct_obj.layout == .Extern) { + // For extern structs, field aligment might be bigger than type's natural alignment. Eg, in + // `extern struct { x: u32, y: u16 }` the second field is aligned as u32. + const field_offset = struct_ty.structFieldOffset(field_index, mod); + ptr_ty_data.flags.alignment = Alignment.fromByteUnits( + if (parent_align == 0) 0 else std.math.gcd(field_offset, parent_align), + ); } else { // Our alignment is capped at the field alignment const field_align = try sema.structFieldAlignment(field, struct_obj.layout); |
