| author | |
| committer | |
| log | d214b6bdf05204377d897afe3eacc0cac33c59a3 |
| tree | 96fabebd64e369018b1fa4d24a784bb2cb15b33a |
| parent | b0e8bf15f5017cf101eb31f74dd264eaf136045f |
3 files changed, 27 insertions(+), 1 deletions(-)
src/Sema.zig+5-1| ... | @@ -20197,7 +20197,11 @@ fn beginComptimePtrLoad( | ... | @@ -20197,7 +20197,11 @@ fn beginComptimePtrLoad( |
| 20197 | var deref = try beginComptimePtrLoad(sema, block, src, field_ptr.container_ptr, field_ptr.container_ty); | 20197 | var deref = try beginComptimePtrLoad(sema, block, src, field_ptr.container_ptr, field_ptr.container_ty); |
| 20198 | 20198 | ||
| 20199 | if (field_ptr.container_ty.hasWellDefinedLayout()) { | 20199 | if (field_ptr.container_ty.hasWellDefinedLayout()) { |
| 20200 | if (deref.parent) |*parent| { | 20200 | const struct_ty = field_ptr.container_ty.castTag(.@"struct"); |
| 20201 | if (struct_ty != null and struct_ty.?.data.layout == .Packed) { | ||
| 20202 | // packed structs are not byte addressable | ||
| 20203 | deref.parent = null; | ||
| 20204 | } else if (deref.parent) |*parent| { | ||
| 20201 | // Update the byte offset (in-place) | 20205 | // Update the byte offset (in-place) |
| 20202 | try sema.resolveTypeLayout(block, src, field_ptr.container_ty); | 20206 | try sema.resolveTypeLayout(block, src, field_ptr.container_ty); |
| 20203 | const field_offset = field_ptr.container_ty.structFieldOffset(field_index, target); | 20207 | const field_offset = field_ptr.container_ty.structFieldOffset(field_index, target); |
src/value.zig+1| ... | @@ -2645,6 +2645,7 @@ pub const Value = extern union { | ... | @@ -2645,6 +2645,7 @@ pub const Value = extern union { |
| 2645 | } | 2645 | } |
| 2646 | unreachable; | 2646 | unreachable; |
| 2647 | }, | 2647 | }, |
| 2648 | .undef => return Value.undef, | ||
| 2648 | 2649 | ||
| 2649 | else => unreachable, | 2650 | else => unreachable, |
| 2650 | } | 2651 | } |
test/behavior/struct.zig+21| ... | @@ -1319,3 +1319,24 @@ test "packed struct aggregate init" { | ... | @@ -1319,3 +1319,24 @@ test "packed struct aggregate init" { |
| 1319 | const result = @bitCast(u8, S.foo(1, 2)); | 1319 | const result = @bitCast(u8, S.foo(1, 2)); |
| 1320 | try expect(result == 9); | 1320 | try expect(result == 9); |
| 1321 | } | 1321 | } |
| 1322 | |||
| 1323 | test "packed struct field access via pointer" { | ||
| 1324 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 1325 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 1326 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 1327 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 1328 | |||
| 1329 | const S = struct { | ||
| 1330 | fn doTheTest() !void { | ||
| 1331 | const S = packed struct { a: u30 }; | ||
| 1332 | var s1: S = .{ .a = 1 }; | ||
| 1333 | var s2 = &s1; | ||
| 1334 | try expect(s2.a == 1); | ||
| 1335 | var s3: S = undefined; | ||
| 1336 | var s4 = &s3; | ||
| 1337 | _ = s4; | ||
| 1338 | } | ||
| 1339 | }; | ||
| 1340 | try S.doTheTest(); | ||
| 1341 | comptime try S.doTheTest(); | ||
| 1342 | } |