mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
x86_64: fix passing register-sized payload as non-reigster-sized union
Closes #17885
This commit is contained in:
parent
62e67a2b56
commit
9ced27dace
@ -1887,7 +1887,7 @@ pub fn loadUnionType(ip: *InternPool, key: Key.UnionType) UnionType {
|
|||||||
.namespace = type_union.data.namespace,
|
.namespace = type_union.data.namespace,
|
||||||
.enum_tag_ty = enum_ty,
|
.enum_tag_ty = enum_ty,
|
||||||
.int_tag_ty = enum_info.tag_ty,
|
.int_tag_ty = enum_info.tag_ty,
|
||||||
.size = type_union.data.padding,
|
.size = type_union.data.size,
|
||||||
.padding = type_union.data.padding,
|
.padding = type_union.data.padding,
|
||||||
.field_names = enum_info.names,
|
.field_names = enum_info.names,
|
||||||
.names_map = enum_info.names_map,
|
.names_map = enum_info.names_map,
|
||||||
|
|||||||
@ -15323,10 +15323,11 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
|
|||||||
const src_ty = self.typeOf(extra.init);
|
const src_ty = self.typeOf(extra.init);
|
||||||
const src_mcv = try self.resolveInst(extra.init);
|
const src_mcv = try self.resolveInst(extra.init);
|
||||||
if (layout.tag_size == 0) {
|
if (layout.tag_size == 0) {
|
||||||
if (self.reuseOperand(inst, extra.init, 0, src_mcv)) break :result src_mcv;
|
if (layout.abi_size <= src_ty.abiSize(mod) and
|
||||||
|
self.reuseOperand(inst, extra.init, 0, src_mcv)) break :result src_mcv;
|
||||||
|
|
||||||
const dst_mcv = try self.allocRegOrMem(inst, true);
|
const dst_mcv = try self.allocRegOrMem(inst, true);
|
||||||
try self.genCopy(union_ty, dst_mcv, src_mcv);
|
try self.genCopy(src_ty, dst_mcv, src_mcv);
|
||||||
break :result dst_mcv;
|
break :result dst_mcv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1881,3 +1881,24 @@ test "union field is a pointer to an aligned version of itself" {
|
|||||||
|
|
||||||
try expect(&e == e.next);
|
try expect(&e == e.next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "pass register-sized field as non-register-sized union" {
|
||||||
|
const S = struct {
|
||||||
|
fn taggedUnion(u: union(enum) { x: usize, y: [2]usize }) !void {
|
||||||
|
try expectEqual(@as(usize, 42), u.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn untaggedUnion(u: union { x: usize, y: [2]usize }) !void {
|
||||||
|
try expectEqual(@as(usize, 42), u.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn externUnion(u: extern union { x: usize, y: [2]usize }) !void {
|
||||||
|
try expectEqual(@as(usize, 42), u.x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var x: usize = 42;
|
||||||
|
try S.taggedUnion(.{ .x = x });
|
||||||
|
try S.untaggedUnion(.{ .x = x });
|
||||||
|
try S.externUnion(.{ .x = x });
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user