Commit 1a2468abfc

Jacob Young <jacobly0@users.noreply.github.com>
2023-06-29 06:04:51
Revert "Sema: preserve extern struct field alignment"
This reverts commit 4620972d086ebb3b7686a79914876488c6dfd171.
1 parent 77dcd90
Changed files (3)
lib
src
test
behavior
lib/std/net.zig
@@ -316,7 +316,7 @@ pub const Ip6Address = extern struct {
                 .addr = undefined,
             },
         };
-        var ip_slice: *[16]u8 = result.sa.addr[0..];
+        var ip_slice = result.sa.addr[0..];
 
         var tail: [16]u8 = undefined;
 
@@ -431,7 +431,7 @@ pub const Ip6Address = extern struct {
                 .addr = undefined,
             },
         };
-        var ip_slice: *[16]u8 = result.sa.addr[0..];
+        var ip_slice = result.sa.addr[0..];
 
         var tail: [16]u8 = undefined;
 
src/Sema.zig
@@ -25926,13 +25926,9 @@ fn structFieldPtrByIndex(
                 ptr_ty_data.packed_offset = .{ .host_size = 0, .bit_offset = 0 };
             }
         }
-    } 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 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 {
         // Our alignment is capped at the field alignment
         const field_align = try sema.structFieldAlignment(field, struct_obj.layout);
test/behavior/struct.zig
@@ -1680,9 +1680,9 @@ test "extern struct field pointer has correct alignment" {
 
     const S = struct {
         fn doTheTest() !void {
-            var a: extern struct { x: u32, y: u16 } = .{ .x = 1, .y = 2 };
-            var b: extern struct { x: u32, y: u16 } align(1) = .{ .x = 3, .y = 4 };
-            var c: extern struct { x: u32, y: u16 } align(64) = .{ .x = 5, .y = 6 };
+            var a: extern struct { x: u32, y: u32 } = .{ .x = 1, .y = 2 };
+            var b: extern struct { x: u32, y: u32 } align(1) = .{ .x = 3, .y = 4 };
+            var c: extern struct { x: u32, y: u32 } align(64) = .{ .x = 5, .y = 6 };
 
             const axp = &a.x;
             const bxp = &b.x;
@@ -1693,19 +1693,18 @@ test "extern struct field pointer has correct alignment" {
 
             comptime assert(@TypeOf(axp) == *u32);
             comptime assert(@TypeOf(bxp) == *align(1) u32);
-            comptime assert(@TypeOf(cxp) == *align(64) u32);
-
-            comptime assert(@TypeOf(ayp) == *align(@alignOf(u32)) u16);
-            comptime assert(@TypeOf(byp) == *align(1) u16);
-            comptime assert(@TypeOf(cyp) == *align(@alignOf(u32)) u16);
+            comptime assert(@TypeOf(cxp) == *align(64) u32); // first field, inherits larger alignment
+            comptime assert(@TypeOf(ayp) == *u32);
+            comptime assert(@TypeOf(byp) == *align(1) u32);
+            comptime assert(@TypeOf(cyp) == *u32);
 
             try expectEqual(@as(u32, 1), axp.*);
             try expectEqual(@as(u32, 3), bxp.*);
             try expectEqual(@as(u32, 5), cxp.*);
 
-            try expectEqual(@as(u16, 2), ayp.*);
-            try expectEqual(@as(u16, 4), byp.*);
-            try expectEqual(@as(u16, 6), cyp.*);
+            try expectEqual(@as(u32, 2), ayp.*);
+            try expectEqual(@as(u32, 4), byp.*);
+            try expectEqual(@as(u32, 6), cyp.*);
         }
     };