aboutsummaryrefslogtreecommitdiff
path: root/test/behavior/field_parent_ptr.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2024-03-31 01:47:23 -0700
committerGitHub <noreply@github.com>2024-03-31 01:47:23 -0700
commita6ed3e6d29b0e2cedfc20048b014cff4e0ae4eaa (patch)
tree11b933e936d64f00a7a820a21afe2633b34d5941 /test/behavior/field_parent_ptr.zig
parentaff71c6132fd17c6fa455a6e7b9f53567e3e55b2 (diff)
parente5ba70bb5c176ba553a5458f89004b44da2b93d6 (diff)
downloadzig-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.zig1966
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);
+ }
}