Commit d214b6bdf0

Veikka Tuominen <git@vexu.eu>
2022-05-25 17:08:51
stage2: packed struct fields do not have a byte offset
1 parent b0e8bf1
Changed files (3)
src
test
behavior
src/Sema.zig
@@ -20197,7 +20197,11 @@ fn beginComptimePtrLoad(
             var deref = try beginComptimePtrLoad(sema, block, src, field_ptr.container_ptr, field_ptr.container_ty);
 
             if (field_ptr.container_ty.hasWellDefinedLayout()) {
-                if (deref.parent) |*parent| {
+                const struct_ty = field_ptr.container_ty.castTag(.@"struct");
+                if (struct_ty != null and struct_ty.?.data.layout == .Packed) {
+                    // packed structs are not byte addressable
+                    deref.parent = null;
+                } else if (deref.parent) |*parent| {
                     // Update the byte offset (in-place)
                     try sema.resolveTypeLayout(block, src, field_ptr.container_ty);
                     const field_offset = field_ptr.container_ty.structFieldOffset(field_index, target);
src/value.zig
@@ -2645,6 +2645,7 @@ pub const Value = extern union {
                 }
                 unreachable;
             },
+            .undef => return Value.undef,
 
             else => unreachable,
         }
test/behavior/struct.zig
@@ -1319,3 +1319,24 @@ test "packed struct aggregate init" {
     const result = @bitCast(u8, S.foo(1, 2));
     try expect(result == 9);
 }
+
+test "packed struct field access via pointer" {
+    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+
+    const S = struct {
+        fn doTheTest() !void {
+            const S = packed struct { a: u30 };
+            var s1: S = .{ .a = 1 };
+            var s2 = &s1;
+            try expect(s2.a == 1);
+            var s3: S = undefined;
+            var s4 = &s3;
+            _ = s4;
+        }
+    };
+    try S.doTheTest();
+    comptime try S.doTheTest();
+}