| author | |
| committer | |
| log | 4620972d086ebb3b7686a79914876488c6dfd171 |
| tree | 8f2f47f0a02deb0f535f77b38a801d0259ac1745 |
| parent | 28f515acd7bb6e008fcb2e9f760053f0c9e97992 |
In
extern struct { x: u32, y: u16 }
we actually know that y's alignment is `@alignOf(u32)`, and not just
`@alignOf(u16)`.
closes: #161343 files changed, 20 insertions(+), 15 deletions(-)
lib/std/net.zig+2-2| ... | ... | @@ -316,7 +316,7 @@ pub const Ip6Address = extern struct { |
| 316 | 316 | .addr = undefined, |
| 317 | 317 | }, |
| 318 | 318 | }; |
| 319 | var ip_slice = result.sa.addr[0..]; | |
| 319 | var ip_slice: *[16]u8 = result.sa.addr[0..]; | |
| 320 | 320 | |
| 321 | 321 | var tail: [16]u8 = undefined; |
| 322 | 322 | |
| ... | ... | @@ -431,7 +431,7 @@ pub const Ip6Address = extern struct { |
| 431 | 431 | .addr = undefined, |
| 432 | 432 | }, |
| 433 | 433 | }; |
| 434 | var ip_slice = result.sa.addr[0..]; | |
| 434 | var ip_slice: *[16]u8 = result.sa.addr[0..]; | |
| 435 | 435 | |
| 436 | 436 | var tail: [16]u8 = undefined; |
| 437 | 437 |
src/Sema.zig+7-3| ... | ... | @@ -25926,9 +25926,13 @@ fn structFieldPtrByIndex( |
| 25926 | 25926 | ptr_ty_data.packed_offset = .{ .host_size = 0, .bit_offset = 0 }; |
| 25927 | 25927 | } |
| 25928 | 25928 | } |
| 25929 | } else if (struct_obj.layout == .Extern and field_index == 0) { | |
| 25930 | // This is the first field in memory, so can inherit the struct alignment | |
| 25931 | ptr_ty_data.flags.alignment = Alignment.fromByteUnits(parent_align); | |
| 25929 | } else if (struct_obj.layout == .Extern) { | |
| 25930 | // For extern structs, field aligment might be bigger than type's natural alignment. Eg, in | |
| 25931 | // `extern struct { x: u32, y: u16 }` the second field is aligned as u32. | |
| 25932 | const field_offset = struct_ty.structFieldOffset(field_index, mod); | |
| 25933 | ptr_ty_data.flags.alignment = Alignment.fromByteUnits( | |
| 25934 | if (parent_align == 0) 0 else std.math.gcd(field_offset, parent_align), | |
| 25935 | ); | |
| 25932 | 25936 | } else { |
| 25933 | 25937 | // Our alignment is capped at the field alignment |
| 25934 | 25938 | const field_align = try sema.structFieldAlignment(field, struct_obj.layout); |
test/behavior/struct.zig+11-10| ... | ... | @@ -1680,9 +1680,9 @@ test "extern struct field pointer has correct alignment" { |
| 1680 | 1680 | |
| 1681 | 1681 | const S = struct { |
| 1682 | 1682 | fn doTheTest() !void { |
| 1683 | var a: extern struct { x: u32, y: u32 } = .{ .x = 1, .y = 2 }; | |
| 1684 | var b: extern struct { x: u32, y: u32 } align(1) = .{ .x = 3, .y = 4 }; | |
| 1685 | var c: extern struct { x: u32, y: u32 } align(64) = .{ .x = 5, .y = 6 }; | |
| 1683 | var a: extern struct { x: u32, y: u16 } = .{ .x = 1, .y = 2 }; | |
| 1684 | var b: extern struct { x: u32, y: u16 } align(1) = .{ .x = 3, .y = 4 }; | |
| 1685 | var c: extern struct { x: u32, y: u16 } align(64) = .{ .x = 5, .y = 6 }; | |
| 1686 | 1686 | |
| 1687 | 1687 | const axp = &a.x; |
| 1688 | 1688 | const bxp = &b.x; |
| ... | ... | @@ -1693,18 +1693,19 @@ test "extern struct field pointer has correct alignment" { |
| 1693 | 1693 | |
| 1694 | 1694 | comptime assert(@TypeOf(axp) == *u32); |
| 1695 | 1695 | comptime assert(@TypeOf(bxp) == *align(1) u32); |
| 1696 | comptime assert(@TypeOf(cxp) == *align(64) u32); // first field, inherits larger alignment | |
| 1697 | comptime assert(@TypeOf(ayp) == *u32); | |
| 1698 | comptime assert(@TypeOf(byp) == *align(1) u32); | |
| 1699 | comptime assert(@TypeOf(cyp) == *u32); | |
| 1696 | comptime assert(@TypeOf(cxp) == *align(64) u32); | |
| 1697 | ||
| 1698 | comptime assert(@TypeOf(ayp) == *align(@alignOf(u32)) u16); | |
| 1699 | comptime assert(@TypeOf(byp) == *align(1) u16); | |
| 1700 | comptime assert(@TypeOf(cyp) == *align(@alignOf(u32)) u16); | |
| 1700 | 1701 | |
| 1701 | 1702 | try expectEqual(@as(u32, 1), axp.*); |
| 1702 | 1703 | try expectEqual(@as(u32, 3), bxp.*); |
| 1703 | 1704 | try expectEqual(@as(u32, 5), cxp.*); |
| 1704 | 1705 | |
| 1705 | try expectEqual(@as(u32, 2), ayp.*); | |
| 1706 | try expectEqual(@as(u32, 4), byp.*); | |
| 1707 | try expectEqual(@as(u32, 6), cyp.*); | |
| 1706 | try expectEqual(@as(u16, 2), ayp.*); | |
| 1707 | try expectEqual(@as(u16, 4), byp.*); | |
| 1708 | try expectEqual(@as(u16, 6), cyp.*); | |
| 1708 | 1709 | } |
| 1709 | 1710 | }; |
| 1710 | 1711 |