mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
Sema: fix union init with zero size field
This commit is contained in:
parent
1b5cbf0d08
commit
a2ad8517ee
12
src/Sema.zig
12
src/Sema.zig
@ -4624,6 +4624,8 @@ fn validateUnionInit(
|
||||
// If the union is comptime, we want `first_block_index`
|
||||
// to point at %c so that the bitcast becomes the last instruction in the block.
|
||||
//
|
||||
// Store instruction may be missing; if field type has only one possible value, this case is handled below.
|
||||
//
|
||||
// In the case of a comptime-known pointer to a union, the
|
||||
// the field_ptr instruction is missing, so we have to pattern-match
|
||||
// based only on the store instructions.
|
||||
@ -4634,7 +4636,10 @@ fn validateUnionInit(
|
||||
var init_val: ?Value = null;
|
||||
while (block_index > 0) : (block_index -= 1) {
|
||||
const store_inst = block.instructions.items[block_index];
|
||||
if (store_inst.toRef() == field_ptr_ref) break;
|
||||
if (store_inst.toRef() == field_ptr_ref) {
|
||||
first_block_index = block_index;
|
||||
break;
|
||||
}
|
||||
switch (air_tags[@intFromEnum(store_inst)]) {
|
||||
.store, .store_safe => {},
|
||||
else => continue,
|
||||
@ -4659,6 +4664,11 @@ fn validateUnionInit(
|
||||
|
||||
const tag_ty = union_ty.unionTagTypeHypothetical(mod);
|
||||
const tag_val = try mod.enumValueFieldIndex(tag_ty, field_index);
|
||||
const field_type = union_ty.unionFieldType(tag_val, mod).?;
|
||||
|
||||
if (try sema.typeHasOnePossibleValue(field_type)) |field_only_value| {
|
||||
init_val = field_only_value;
|
||||
}
|
||||
|
||||
if (init_val) |val| {
|
||||
// Our task is to delete all the `field_ptr` and `store` instructions, and insert
|
||||
|
||||
@ -381,6 +381,26 @@ test "union with only 1 field which is void should be zero bits" {
|
||||
comptime assert(@sizeOf(ZeroBits) == 0);
|
||||
}
|
||||
|
||||
test "assigning to union with zero size field" {
|
||||
const U = union {
|
||||
a: u32,
|
||||
b: void,
|
||||
c: f32,
|
||||
};
|
||||
|
||||
const u: U = .{ .b = {} };
|
||||
_ = u;
|
||||
|
||||
const UE = union(enum) {
|
||||
a: f32,
|
||||
b: u32,
|
||||
c: u0,
|
||||
};
|
||||
|
||||
const ue: UE = .{ .c = 0 };
|
||||
_ = ue;
|
||||
}
|
||||
|
||||
test "tagged union initialization with runtime void" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user