Files
zig/test/behavior/field_parent_ptr.zig
T
Pavel Verigo 2802276091 stage2-wasm: address TODO in instruction selection code
This PR started as addressing the long-standing TODO above `buildOpcode`:

    /// TODO: deprecated, should be split up per tag.

The code around this area was written a long time ago and has effectively
become a legacy approach. When I started doing semi-occasional work for
bringing >128-bit integer operations to the wasm backend, which is
the last big missing piece of this backend, this design became annoying.

While thinking about how to support that work, and also how vector unrolling
should be handled (in cases where we do not rely purely on the legalize pass),
I decided to do some architectural changes were needed.

The first step is removing helpers like `intBinOp`, `floatBinOp`, `UnOp`, etc.
They do not really capture all operations and resulted in a lot of small
pieces of code trying to artificially unify different ops.

Instead, the direction taken here is similar to `Sema/arith.zig`,  introduce
backend-oriented helpers such as `int*Op*Scalar` and `float*Op*` that operate
purely in backend structures without referencing AIR at all.

Additionally, the idea of introducing dedicated `IntType` and `FloatType`
types was chosen. Using `Type` from Sema inside the backend is awkward,
especially when strange or temporary types are needed. Creating them through
`PerThread` is also undesirable since the backend strives to not modify
`InternPool`. This goal is not fully achieved yet, some parts still require
changes, and `InternPool` type formatting still requires `pt` for error
reporting.

This PR also enables legalize passes for some packed operations. The previous
code in this area was buggy, and given the current state of the backend,
relying on legalization is simpler.

Finally, this PR disables one behavior test: `atomicrmw` with floats. The test
seems to only run the non-concurrency path, because it would crash otherwise,
and since we do not currently run behavior tests for the self-hosted backend
with concurrency or atomics enabled, it does not provide meaningful coverage yet.

In summary, this refactor reworks instruction selection in the wasm backend
to simplify the code and make future work, especially adding big integer
support.
2026-03-11 22:46:58 +01:00

1972 lines
55 KiB
Zig

const expect = @import("std").testing.expect;
const builtin = @import("builtin");
test "@fieldParentPtr struct" {
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const C = struct {
a: bool = true,
b: f32 = 3.14,
c: struct { u8 } = .{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);
}
{
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 extern struct" {
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
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);
}
{
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 extern struct first zero-bit field" {
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
const C = extern 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 extern struct middle zero-bit field" {
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
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 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 extern struct last zero-bit field" {
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
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_spirv) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) 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);
}
{
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 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_spirv) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) 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_spirv) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) 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 C = packed struct {
a: u9,
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);
}
}
}
test "@fieldParentPtr packed struct first zero-bit field" {
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) 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_spirv) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) 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_spirv) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) 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_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
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);
}
{
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 untagged union" {
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
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 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);
}
{
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_c) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
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_spirv) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.target.cpu.arch.endian() == .big) return error.SkipZigTest; // TODO
const C = packed union {
a: packed struct(u32) {
a: bool,
b: u31 = 0,
},
b: f32,
c: packed struct(u32) {
x: u8,
b: u24 = 0,
},
d: i32,
};
{
const c: C = .{ .a = .{ .a = false } };
const pcf = &c.a;
const pc: *const C = @alignCast(@fieldParentPtr("a", pcf));
try expect(pc == &c);
}
{
const c: C = .{ .a = .{ .a = false } };
const pcf = &c.a;
var pc: *const C = undefined;
pc = @alignCast(@fieldParentPtr("a", pcf));
try expect(pc == &c);
}
{
const c: C = .{ .a = .{ .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 = .{ .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 tagged union all zero-bit fields" {
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
const C = union(enum) {
a: u0,
b: i0,
};
{
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 = 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);
}
}