diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2024-03-31 01:47:23 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-31 01:47:23 -0700 |
| commit | a6ed3e6d29b0e2cedfc20048b014cff4e0ae4eaa (patch) | |
| tree | 11b933e936d64f00a7a820a21afe2633b34d5941 /test/behavior/field_parent_ptr.zig | |
| parent | aff71c6132fd17c6fa455a6e7b9f53567e3e55b2 (diff) | |
| parent | e5ba70bb5c176ba553a5458f89004b44da2b93d6 (diff) | |
| download | zig-a6ed3e6d29b0e2cedfc20048b014cff4e0ae4eaa.tar.gz zig-a6ed3e6d29b0e2cedfc20048b014cff4e0ae4eaa.zip | |
Merge pull request #19470 from jacobly0/field-parent-ptr
Rework `@fieldParentPtr` to use RLS
Diffstat (limited to 'test/behavior/field_parent_ptr.zig')
| -rw-r--r-- | test/behavior/field_parent_ptr.zig | 1966 |
1 files changed, 1882 insertions, 84 deletions
diff --git a/test/behavior/field_parent_ptr.zig b/test/behavior/field_parent_ptr.zig index adb0e66ed6..bd2063a3a3 100644 --- a/test/behavior/field_parent_ptr.zig +++ b/test/behavior/field_parent_ptr.zig @@ -1,126 +1,1924 @@ const expect = @import("std").testing.expect; const builtin = @import("builtin"); -test "@fieldParentPtr non-first field" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO +test "@fieldParentPtr struct" { + const C = struct { + a: bool = true, + b: f32 = 3.14, + c: struct { u8 } = .{42}, + d: i32 = 12345, + }; - try testParentFieldPtr(&foo.c); - try comptime testParentFieldPtr(&foo.c); + { + const c: C = .{ .a = false }; + const pcf = &c.a; + const pc: *const C = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = false }; + const pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = false }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .a = false }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .b = 666.667 }; + const pcf = &c.b; + const pc: *const C = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 666.667 }; + const pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 666.667 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .b = 666.667 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .c = .{255} }; + const pcf = &c.c; + const pc: *const C = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = .{255} }; + const pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = .{255} }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .c = .{255} }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .d = -1111111111 }; + const pcf = &c.d; + const pc: *const C = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .d = -1111111111 }; + const pcf = &c.d; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .d = -1111111111 }; + var pcf: @TypeOf(&c.d) = undefined; + pcf = &c.d; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .d = -1111111111 }; + var pcf: @TypeOf(&c.d) = undefined; + pcf = &c.d; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } } -test "@fieldParentPtr first field" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO +test "@fieldParentPtr extern struct" { + const C = extern struct { + a: bool = true, + b: f32 = 3.14, + c: extern struct { x: u8 } = .{ .x = 42 }, + d: i32 = 12345, + }; + + { + const c: C = .{ .a = false }; + const pcf = &c.a; + const pc: *const C = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = false }; + const pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = false }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .a = false }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .b = 666.667 }; + const pcf = &c.b; + const pc: *const C = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 666.667 }; + const pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 666.667 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .b = 666.667 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } - try testParentFieldPtrFirst(&foo.a); - try comptime testParentFieldPtrFirst(&foo.a); + { + const c: C = .{ .c = .{ .x = 255 } }; + const pcf = &c.c; + const pc: *const C = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = .{ .x = 255 } }; + const pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = .{ .x = 255 } }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .c = .{ .x = 255 } }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .d = -1111111111 }; + const pcf = &c.d; + const pc: *const C = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .d = -1111111111 }; + const pcf = &c.d; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .d = -1111111111 }; + var pcf: @TypeOf(&c.d) = undefined; + pcf = &c.d; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .d = -1111111111 }; + var pcf: @TypeOf(&c.d) = undefined; + pcf = &c.d; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } } -const Foo = struct { - a: bool, - b: f32, - c: i32, - d: i32, -}; +test "@fieldParentPtr extern struct first zero-bit field" { + const C = extern struct { + a: u0 = 0, + b: f32 = 3.14, + c: i32 = 12345, + }; -const foo = Foo{ - .a = true, - .b = 0.123, - .c = 1234, - .d = -10, -}; + { + const c: C = .{ .a = 0 }; + const pcf = &c.a; + const pc: *const C = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = 0 }; + const pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = 0 }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .a = 0 }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } -fn testParentFieldPtr(c: *const i32) !void { - try expect(c == &foo.c); + { + const c: C = .{ .b = 666.667 }; + const pcf = &c.b; + const pc: *const C = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 666.667 }; + const pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 666.667 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .b = 666.667 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } - const base = @fieldParentPtr(Foo, "c", c); - try expect(base == &foo); - try expect(&base.c == c); + { + const c: C = .{ .c = -1111111111 }; + const pcf = &c.c; + const pc: *const C = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = -1111111111 }; + const pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = -1111111111 }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .c = -1111111111 }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } } -fn testParentFieldPtrFirst(a: *const bool) !void { - try expect(a == &foo.a); +test "@fieldParentPtr extern struct middle zero-bit field" { + const C = extern struct { + a: f32 = 3.14, + b: u0 = 0, + c: i32 = 12345, + }; + + { + const c: C = .{ .a = 666.667 }; + const pcf = &c.a; + const pc: *const C = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = 666.667 }; + const pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = 666.667 }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .a = 666.667 }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } - const base = @fieldParentPtr(Foo, "a", a); - try expect(base == &foo); - try expect(&base.a == a); + { + const c: C = .{ .b = 0 }; + const pcf = &c.b; + const pc: *const C = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 0 }; + const pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 0 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .b = 0 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .c = -1111111111 }; + const pcf = &c.c; + const pc: *const C = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = -1111111111 }; + const pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = -1111111111 }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .c = -1111111111 }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } } -test "@fieldParentPtr untagged union" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO +test "@fieldParentPtr extern struct last zero-bit field" { + const C = extern struct { + a: f32 = 3.14, + b: i32 = 12345, + c: u0 = 0, + }; + + { + const c: C = .{ .a = 666.667 }; + const pcf = &c.a; + const pc: *const C = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = 666.667 }; + const pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = 666.667 }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .a = 666.667 }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .b = -1111111111 }; + const pcf = &c.b; + const pc: *const C = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = -1111111111 }; + const pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = -1111111111 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .b = -1111111111 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .c = 0 }; + const pcf = &c.c; + const pc: *const C = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = 0 }; + const pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = 0 }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .c = 0 }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } +} + +test "@fieldParentPtr unaligned packed struct" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; + + const C = packed struct { + a: bool = true, + b: f32 = 3.14, + c: packed struct { x: u8 } = .{ .x = 42 }, + d: i32 = 12345, + }; + + { + const c: C = .{ .a = false }; + const pcf = &c.a; + const pc: *const C = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = false }; + const pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = false }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .a = false }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .b = 666.667 }; + const pcf = &c.b; + const pc: *const C = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 666.667 }; + const pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 666.667 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .b = 666.667 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } - try testFieldParentPtrUnion(&bar.c); - try comptime testFieldParentPtrUnion(&bar.c); + { + const c: C = .{ .c = .{ .x = 255 } }; + const pcf = &c.c; + const pc: *const C = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = .{ .x = 255 } }; + const pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = .{ .x = 255 } }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .c = .{ .x = 255 } }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .d = -1111111111 }; + const pcf = &c.d; + const pc: *const C = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .d = -1111111111 }; + const pcf = &c.d; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .d = -1111111111 }; + var pcf: @TypeOf(&c.d) = undefined; + pcf = &c.d; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .d = -1111111111 }; + var pcf: @TypeOf(&c.d) = undefined; + pcf = &c.d; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } } -const Bar = union(enum) { - a: bool, - b: f32, - c: i32, - d: i32, -}; +test "@fieldParentPtr aligned packed struct" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; + + const C = packed struct { + a: f32 = 3.14, + b: i32 = 12345, + c: packed struct { x: u8 } = .{ .x = 42 }, + d: bool = true, + }; + + { + const c: C = .{ .a = 666.667 }; + const pcf = &c.a; + const pc: *const C = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = 666.667 }; + const pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = 666.667 }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .a = 666.667 }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .b = -1111111111 }; + const pcf = &c.b; + const pc: *const C = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = -1111111111 }; + const pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = -1111111111 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .b = -1111111111 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .c = .{ .x = 255 } }; + const pcf = &c.c; + const pc: *const C = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = .{ .x = 255 } }; + const pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = .{ .x = 255 } }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .c = .{ .x = 255 } }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .d = false }; + const pcf = &c.d; + const pc: *const C = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .d = false }; + const pcf = &c.d; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .d = false }; + var pcf: @TypeOf(&c.d) = undefined; + pcf = &c.d; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .d = false }; + var pcf: @TypeOf(&c.d) = undefined; + pcf = &c.d; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } +} + +test "@fieldParentPtr nested packed struct" { + if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; + + { + const C = packed struct { + a: u8, + b: packed struct { + a: u8, + b: packed struct { + a: u8, + }, + }, + }; + + { + const c: C = .{ .a = 0, .b = .{ .a = 0, .b = .{ .a = 0 } } }; + const pcbba = &c.b.b.a; + const pcbb: @TypeOf(&c.b.b) = @alignCast(@fieldParentPtr("a", pcbba)); + try expect(pcbb == &c.b.b); + const pcb: @TypeOf(&c.b) = @alignCast(@fieldParentPtr("b", pcbb)); + try expect(pcb == &c.b); + const pc: *const C = @alignCast(@fieldParentPtr("b", pcb)); + try expect(pc == &c); + } + + { + var c: C = undefined; + c = .{ .a = 0, .b = .{ .a = 0, .b = .{ .a = 0 } } }; + var pcbba: @TypeOf(&c.b.b.a) = undefined; + pcbba = &c.b.b.a; + var pcbb: @TypeOf(&c.b.b) = undefined; + pcbb = @alignCast(@fieldParentPtr("a", pcbba)); + try expect(pcbb == &c.b.b); + var pcb: @TypeOf(&c.b) = undefined; + pcb = @alignCast(@fieldParentPtr("b", pcbb)); + try expect(pcb == &c.b); + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcb)); + try expect(pc == &c); + } + } + + { + const C = packed struct { + a: u8, + b: packed struct { + a: u9, + b: packed struct { + a: u8, + }, + }, + }; + + { + const c: C = .{ .a = 0, .b = .{ .a = 0, .b = .{ .a = 0 } } }; + const pcbba = &c.b.b.a; + const pcbb: @TypeOf(&c.b.b) = @alignCast(@fieldParentPtr("a", pcbba)); + try expect(pcbb == &c.b.b); + const pcb: @TypeOf(&c.b) = @alignCast(@fieldParentPtr("b", pcbb)); + try expect(pcb == &c.b); + const pc: *const C = @alignCast(@fieldParentPtr("b", pcb)); + try expect(pc == &c); + } + + { + var c: C = undefined; + c = .{ .a = 0, .b = .{ .a = 0, .b = .{ .a = 0 } } }; + var pcbba: @TypeOf(&c.b.b.a) = undefined; + pcbba = &c.b.b.a; + var pcbb: @TypeOf(&c.b.b) = undefined; + pcbb = @alignCast(@fieldParentPtr("a", pcbba)); + try expect(pcbb == &c.b.b); + var pcb: @TypeOf(&c.b) = undefined; + pcb = @alignCast(@fieldParentPtr("b", pcbb)); + try expect(pcb == &c.b); + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcb)); + try expect(pc == &c); + } + } + + { + const C = packed struct { + a: u9, + b: packed struct { + a: u7, + b: packed struct { + a: u8, + }, + }, + }; + + { + const c: C = .{ .a = 0, .b = .{ .a = 0, .b = .{ .a = 0 } } }; + const pcbba = &c.b.b.a; + const pcbb: @TypeOf(&c.b.b) = @alignCast(@fieldParentPtr("a", pcbba)); + try expect(pcbb == &c.b.b); + const pcb: @TypeOf(&c.b) = @alignCast(@fieldParentPtr("b", pcbb)); + try expect(pcb == &c.b); + const pc: *const C = @alignCast(@fieldParentPtr("b", pcb)); + try expect(pc == &c); + } + + { + var c: C = undefined; + c = .{ .a = 0, .b = .{ .a = 0, .b = .{ .a = 0 } } }; + var pcbba: @TypeOf(&c.b.b.a) = undefined; + pcbba = &c.b.b.a; + var pcbb: @TypeOf(&c.b.b) = undefined; + pcbb = @alignCast(@fieldParentPtr("a", pcbba)); + try expect(pcbb == &c.b.b); + var pcb: @TypeOf(&c.b) = undefined; + pcb = @alignCast(@fieldParentPtr("b", pcbb)); + try expect(pcb == &c.b); + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcb)); + try expect(pc == &c); + } + } -const bar = Bar{ .c = 42 }; + { + const C = packed struct { + a: u9, + b: packed struct { + a: u8, + b: packed struct { + a: u8, + }, + }, + }; -fn testFieldParentPtrUnion(c: *const i32) !void { - try expect(c == &bar.c); + { + const c: C = .{ .a = 0, .b = .{ .a = 0, .b = .{ .a = 0 } } }; + const pcbba = &c.b.b.a; + const pcbb: @TypeOf(&c.b.b) = @alignCast(@fieldParentPtr("a", pcbba)); + try expect(pcbb == &c.b.b); + const pcb: @TypeOf(&c.b) = @alignCast(@fieldParentPtr("b", pcbb)); + try expect(pcb == &c.b); + const pc: *const C = @alignCast(@fieldParentPtr("b", pcb)); + try expect(pc == &c); + } - const base = @fieldParentPtr(Bar, "c", c); - try expect(base == &bar); - try expect(&base.c == c); + { + var c: C = undefined; + c = .{ .a = 0, .b = .{ .a = 0, .b = .{ .a = 0 } } }; + var pcbba: @TypeOf(&c.b.b.a) = undefined; + pcbba = &c.b.b.a; + var pcbb: @TypeOf(&c.b.b) = undefined; + pcbb = @alignCast(@fieldParentPtr("a", pcbba)); + try expect(pcbb == &c.b.b); + var pcb: @TypeOf(&c.b) = undefined; + pcb = @alignCast(@fieldParentPtr("b", pcbb)); + try expect(pcb == &c.b); + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcb)); + try expect(pc == &c); + } + } +} + +test "@fieldParentPtr packed struct first zero-bit field" { + if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; + + const C = packed struct { + a: u0 = 0, + b: f32 = 3.14, + c: i32 = 12345, + }; + + { + const c: C = .{ .a = 0 }; + const pcf = &c.a; + const pc: *const C = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = 0 }; + const pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = 0 }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .a = 0 }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .b = 666.667 }; + const pcf = &c.b; + const pc: *const C = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 666.667 }; + const pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 666.667 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .b = 666.667 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .c = -1111111111 }; + const pcf = &c.c; + const pc: *const C = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = -1111111111 }; + const pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = -1111111111 }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .c = -1111111111 }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } +} + +test "@fieldParentPtr packed struct middle zero-bit field" { + if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; + + const C = packed struct { + a: f32 = 3.14, + b: u0 = 0, + c: i32 = 12345, + }; + + { + const c: C = .{ .a = 666.667 }; + const pcf = &c.a; + const pc: *const C = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = 666.667 }; + const pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = 666.667 }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .a = 666.667 }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .b = 0 }; + const pcf = &c.b; + const pc: *const C = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 0 }; + const pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 0 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .b = 0 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .c = -1111111111 }; + const pcf = &c.c; + const pc: *const C = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = -1111111111 }; + const pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = -1111111111 }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .c = -1111111111 }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } +} + +test "@fieldParentPtr packed struct last zero-bit field" { + if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; + + const C = packed struct { + a: f32 = 3.14, + b: i32 = 12345, + c: u0 = 0, + }; + + { + const c: C = .{ .a = 666.667 }; + const pcf = &c.a; + const pc: *const C = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = 666.667 }; + const pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = 666.667 }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .a = 666.667 }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .b = -1111111111 }; + const pcf = &c.b; + const pc: *const C = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = -1111111111 }; + const pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = -1111111111 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .b = -1111111111 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .c = 0 }; + const pcf = &c.c; + const pc: *const C = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = 0 }; + const pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = 0 }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .c = 0 }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } } test "@fieldParentPtr tagged union" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + const C = union(enum) { + a: bool, + b: f32, + c: struct { u8 }, + d: i32, + }; + + { + const c: C = .{ .a = false }; + const pcf = &c.a; + const pc: *const C = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = false }; + const pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = false }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .a = false }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .b = 0 }; + const pcf = &c.b; + const pc: *const C = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 0 }; + const pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 0 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .b = 0 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .c = .{255} }; + const pcf = &c.c; + const pc: *const C = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = .{255} }; + const pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = .{255} }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .c = .{255} }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } - try testFieldParentPtrTaggedUnion(&bar_tagged.c); - try comptime testFieldParentPtrTaggedUnion(&bar_tagged.c); + { + const c: C = .{ .d = -1111111111 }; + const pcf = &c.d; + const pc: *const C = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .d = -1111111111 }; + const pcf = &c.d; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .d = -1111111111 }; + var pcf: @TypeOf(&c.d) = undefined; + pcf = &c.d; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .d = -1111111111 }; + var pcf: @TypeOf(&c.d) = undefined; + pcf = &c.d; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } } -const BarTagged = union(enum) { - a: bool, - b: f32, - c: i32, - d: i32, -}; +test "@fieldParentPtr untagged union" { + const C = union { + a: bool, + b: f32, + c: struct { u8 }, + d: i32, + }; + + { + const c: C = .{ .a = false }; + const pcf = &c.a; + const pc: *const C = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = false }; + const pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = false }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .a = false }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } -const bar_tagged = BarTagged{ .c = 42 }; + { + const c: C = .{ .b = 0 }; + const pcf = &c.b; + const pc: *const C = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 0 }; + const pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 0 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .b = 0 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } -fn testFieldParentPtrTaggedUnion(c: *const i32) !void { - try expect(c == &bar_tagged.c); + { + const c: C = .{ .c = .{255} }; + const pcf = &c.c; + const pc: *const C = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = .{255} }; + const pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = .{255} }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .c = .{255} }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } - const base = @fieldParentPtr(BarTagged, "c", c); - try expect(base == &bar_tagged); - try expect(&base.c == c); + { + const c: C = .{ .d = -1111111111 }; + const pcf = &c.d; + const pc: *const C = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .d = -1111111111 }; + const pcf = &c.d; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .d = -1111111111 }; + var pcf: @TypeOf(&c.d) = undefined; + pcf = &c.d; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .d = -1111111111 }; + var pcf: @TypeOf(&c.d) = undefined; + pcf = &c.d; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } } test "@fieldParentPtr extern union" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + const C = extern union { + a: bool, + b: f32, + c: extern struct { x: u8 }, + d: i32, + }; + + { + const c: C = .{ .a = false }; + const pcf = &c.a; + const pc: *const C = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = false }; + const pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = false }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .a = false }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .b = 0 }; + const pcf = &c.b; + const pc: *const C = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 0 }; + const pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 0 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .b = 0 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .c = .{ .x = 255 } }; + const pcf = &c.c; + const pc: *const C = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = .{ .x = 255 } }; + const pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = .{ .x = 255 } }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .c = .{ .x = 255 } }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .d = -1111111111 }; + const pcf = &c.d; + const pc: *const C = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .d = -1111111111 }; + const pcf = &c.d; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .d = -1111111111 }; + var pcf: @TypeOf(&c.d) = undefined; + pcf = &c.d; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .d = -1111111111 }; + var pcf: @TypeOf(&c.d) = undefined; + pcf = &c.d; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } +} + +test "@fieldParentPtr packed union" { + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; + + const C = packed union { + a: bool, + b: f32, + c: packed struct { x: u8 }, + d: i32, + }; + + { + const c: C = .{ .a = false }; + const pcf = &c.a; + const pc: *const C = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = false }; + const pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = false }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .a = false }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .b = 0 }; + const pcf = &c.b; + const pc: *const C = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 0 }; + const pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 0 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .b = 0 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + + { + const c: C = .{ .c = .{ .x = 255 } }; + const pcf = &c.c; + const pc: *const C = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = .{ .x = 255 } }; + const pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .c = .{ .x = 255 } }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .c = .{ .x = 255 } }; + var pcf: @TypeOf(&c.c) = undefined; + pcf = &c.c; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("c", pcf)); + try expect(pc == &c); + } - try testFieldParentPtrExternUnion(&bar_extern.c); - try comptime testFieldParentPtrExternUnion(&bar_extern.c); + { + const c: C = .{ .d = -1111111111 }; + const pcf = &c.d; + const pc: *const C = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .d = -1111111111 }; + const pcf = &c.d; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .d = -1111111111 }; + var pcf: @TypeOf(&c.d) = undefined; + pcf = &c.d; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .d = -1111111111 }; + var pcf: @TypeOf(&c.d) = undefined; + pcf = &c.d; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("d", pcf)); + try expect(pc == &c); + } } -const BarExtern = extern union { - a: bool, - b: f32, - c: i32, - d: i32, -}; +test "@fieldParentPtr tagged union all zero-bit fields" { + if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; -const bar_extern = BarExtern{ .c = 42 }; + const C = union(enum) { + a: u0, + b: i0, + }; -fn testFieldParentPtrExternUnion(c: *const i32) !void { - try expect(c == &bar_extern.c); + { + const c: C = .{ .a = 0 }; + const pcf = &c.a; + const pc: *const C = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = 0 }; + const pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .a = 0 }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .a = 0 }; + var pcf: @TypeOf(&c.a) = undefined; + pcf = &c.a; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("a", pcf)); + try expect(pc == &c); + } - const base = @fieldParentPtr(BarExtern, "c", c); - try expect(base == &bar_extern); - try expect(&base.c == c); + { + const c: C = .{ .b = 0 }; + const pcf = &c.b; + const pc: *const C = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 0 }; + const pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + const c: C = .{ .b = 0 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *const C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } + { + var c: C = undefined; + c = .{ .b = 0 }; + var pcf: @TypeOf(&c.b) = undefined; + pcf = &c.b; + var pc: *C = undefined; + pc = @alignCast(@fieldParentPtr("b", pcf)); + try expect(pc == &c); + } } |
