authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-08-12 23:18:05+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-08-13 11:36:16+01:00
logba6abd71c2d3664bc658cf5ce55b5c53052dc720
tree116c178b6877cbf07abbeec681768adbaebd7449
parent38ba425b26312ea073c7082e576e8583913139d7
signaturelock-open Commit is signed but in an unrecognized format.

llvm: unions which are equivalent to enums are not by-ref

The LLVM backend lowers unions where all fields are zero-bit as equivalent to their backing enum, and expects them to have the same by-ref-ness in at least one place in the backend, probably more. Resolves: #23577

2 files changed, 16 insertions(+), 1 deletions(-)

src/codegen/llvm.zig+1-1
...@@ -12777,7 +12777,7 @@ fn isByRef(ty: Type, zcu: *Zcu) bool {...@@ -12777,7 +12777,7 @@ fn isByRef(ty: Type, zcu: *Zcu) bool {
12777 },12777 },
12778 .@"union" => switch (ty.containerLayout(zcu)) {12778 .@"union" => switch (ty.containerLayout(zcu)) {
12779 .@"packed" => return false,12779 .@"packed" => return false,
12780 else => return ty.hasRuntimeBits(zcu),12780 else => return ty.hasRuntimeBits(zcu) and !ty.unionHasAllZeroBitFieldTypes(zcu),
12781 },12781 },
12782 .error_union => {12782 .error_union => {
12783 const payload_ty = ty.errorUnionPayload(zcu);12783 const payload_ty = ty.errorUnionPayload(zcu);
test/behavior/cast.zig+15
...@@ -2722,3 +2722,18 @@ test "@intFromFloat vector boundary cases" {...@@ -2722,3 +2722,18 @@ test "@intFromFloat vector boundary cases" {
2722 try S.doTheTest();2722 try S.doTheTest();
2723 try comptime S.doTheTest();2723 try comptime S.doTheTest();
2724}2724}
2725
2726test "coerce enum to union with zero-bit fields through local variables" {
2727 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2728
2729 const E = enum(u1) { foo, bar };
2730 const U = union(E) { foo, bar };
2731
2732 var runtime: E = undefined;
2733 runtime = .foo;
2734
2735 var result: U = undefined;
2736 result = runtime;
2737
2738 try expect(result == .foo);
2739}