mirror of
https://github.com/ziglang/zig.git
synced 2026-02-20 16:24:51 +00:00
parent
d89f39d719
commit
a11da37734
@ -4351,17 +4351,32 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab
|
||||
TypeUnionField *field = instruction->field;
|
||||
|
||||
if (!type_has_bits(field->type_entry)) {
|
||||
if (union_type->data.unionation.gen_tag_index == SIZE_MAX) {
|
||||
ZigType *tag_type = union_type->data.unionation.tag_type;
|
||||
if (!instruction->initializing || !type_has_bits(tag_type))
|
||||
return nullptr;
|
||||
|
||||
// The field has no bits but we still have to change the discriminant
|
||||
// value here
|
||||
LLVMValueRef union_ptr = ir_llvm_value(g, instruction->union_ptr);
|
||||
|
||||
LLVMTypeRef tag_type_ref = get_llvm_type(g, tag_type);
|
||||
LLVMValueRef tag_field_ptr = nullptr;
|
||||
if (union_type->data.unionation.gen_field_count == 0) {
|
||||
assert(union_type->data.unionation.gen_tag_index == SIZE_MAX);
|
||||
// The whole union is collapsed into the discriminant
|
||||
tag_field_ptr = LLVMBuildBitCast(g->builder, union_ptr,
|
||||
LLVMPointerType(tag_type_ref, 0), "");
|
||||
} else {
|
||||
assert(union_type->data.unionation.gen_tag_index != SIZE_MAX);
|
||||
tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr,
|
||||
union_type->data.unionation.gen_tag_index, "");
|
||||
}
|
||||
if (instruction->initializing) {
|
||||
LLVMValueRef union_ptr = ir_llvm_value(g, instruction->union_ptr);
|
||||
LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr,
|
||||
union_type->data.unionation.gen_tag_index, "");
|
||||
LLVMValueRef tag_value = bigint_to_llvm_const(get_llvm_type(g, union_type->data.unionation.tag_type),
|
||||
&field->enum_field->value);
|
||||
gen_store_untyped(g, tag_value, tag_field_ptr, 0, false);
|
||||
}
|
||||
|
||||
LLVMValueRef tag_value = bigint_to_llvm_const(tag_type_ref,
|
||||
&field->enum_field->value);
|
||||
assert(tag_field_ptr != nullptr);
|
||||
gen_store_untyped(g, tag_value, tag_field_ptr, 0, false);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@ -110,7 +110,7 @@ fn doTest() void {
|
||||
}
|
||||
|
||||
fn bar(value: Payload) i32 {
|
||||
expect(@as(Letter,value) == Letter.A);
|
||||
expect(@as(Letter, value) == Letter.A);
|
||||
return switch (value) {
|
||||
Payload.A => |x| return x - 1244,
|
||||
Payload.B => |x| if (x == 12.34) @as(i32, 20) else 21,
|
||||
@ -208,7 +208,7 @@ test "cast union to tag type of union" {
|
||||
}
|
||||
|
||||
fn testCastUnionToTagType(x: TheUnion) void {
|
||||
expect(@as(TheTag,x) == TheTag.B);
|
||||
expect(@as(TheTag, x) == TheTag.B);
|
||||
}
|
||||
|
||||
test "cast tag type of union to union" {
|
||||
@ -558,16 +558,27 @@ test "anonymous union literal syntax" {
|
||||
};
|
||||
|
||||
fn doTheTest() void {
|
||||
var i: Number = .{.int = 42};
|
||||
var i: Number = .{ .int = 42 };
|
||||
var f = makeNumber();
|
||||
expect(i.int == 42);
|
||||
expect(f.float == 12.34);
|
||||
}
|
||||
|
||||
fn makeNumber() Number {
|
||||
return .{.float = 12.34};
|
||||
return .{ .float = 12.34 };
|
||||
}
|
||||
};
|
||||
S.doTheTest();
|
||||
comptime S.doTheTest();
|
||||
}
|
||||
|
||||
test "update the tag value for zero-sized unions" {
|
||||
const S = union(enum) {
|
||||
U0: void,
|
||||
U1: void,
|
||||
};
|
||||
var x = S{ .U0 = {} };
|
||||
expect(x == .U0);
|
||||
x = S{ .U1 = {} };
|
||||
expect(x == .U1);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user