fix union init with void payload

all std lib tests passing now
This commit is contained in:
Andrew Kelley 2019-06-25 11:31:38 -04:00
parent 3021e5ca67
commit c61e0a078c
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
6 changed files with 44 additions and 35 deletions

View File

@ -5001,12 +5001,9 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
field_val->type = wanted_type->data.structure.fields[i].type_entry;
assert(field_val->type);
init_const_undefined(g, field_val);
ConstParent *parent = get_const_val_parent(g, field_val);
if (parent != nullptr) {
parent->id = ConstParentIdStruct;
parent->data.p_struct.struct_val = const_val;
parent->data.p_struct.field_index = i;
}
field_val->parent.id = ConstParentIdStruct;
field_val->parent.data.p_struct.struct_val = const_val;
field_val->parent.data.p_struct.field_index = i;
}
} else {
const_val->special = ConstValSpecialUndef;
@ -5842,11 +5839,6 @@ void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
zig_unreachable();
}
// Deprecated. Reference the parent field directly.
ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) {
return &value->parent;
}
static const ZigTypeId all_type_ids[] = {
ZigTypeIdMetaType,
ZigTypeIdVoid,

View File

@ -180,7 +180,6 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val);
ConstExprValue *create_const_vals(size_t count);
ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value);
void expand_undef_array(CodeGen *g, ConstExprValue *const_val);
void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value);

View File

@ -3873,8 +3873,20 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab
TypeUnionField *field = instruction->field;
if (!type_has_bits(field->type_entry))
if (!type_has_bits(field->type_entry)) {
if (union_type->data.unionation.gen_tag_index == SIZE_MAX) {
return nullptr;
}
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);
}
return nullptr;
}
LLVMValueRef union_ptr = ir_llvm_value(g, instruction->union_ptr);
LLVMTypeRef field_type_ref = LLVMPointerType(get_llvm_type(g, field->type_entry), 0);

View File

@ -17425,11 +17425,9 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
ConstExprValue *field_val = &struct_val->data.x_struct.fields[i];
field_val->special = ConstValSpecialUndef;
field_val->type = struct_type->data.structure.fields[i].type_entry;
ConstParent *parent = get_const_val_parent(ira->codegen, field_val);
assert(parent != nullptr);
parent->id = ConstParentIdStruct;
parent->data.p_struct.struct_val = struct_val;
parent->data.p_struct.field_index = i;
field_val->parent.id = ConstParentIdStruct;
field_val->parent.data.p_struct.struct_val = struct_val;
field_val->parent.data.p_struct.field_index = i;
}
}
IrInstruction *result;
@ -17507,11 +17505,8 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
ConstExprValue *payload_val = create_const_vals(1);
payload_val->special = ConstValSpecialUndef;
payload_val->type = field->type_entry;
ConstParent *parent = get_const_val_parent(ira->codegen, payload_val);
if (parent != nullptr) {
parent->id = ConstParentIdUnion;
parent->data.p_union.union_val = union_val;
}
payload_val->parent.id = ConstParentIdUnion;
payload_val->parent.data.p_union.union_val = union_val;
union_val->special = ConstValSpecialStatic;
bigint_init_bigint(&union_val->data.x_union.tag, &field->enum_field->value);
@ -25289,7 +25284,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdReturnPtr:
case IrInstructionIdTypeOf:
case IrInstructionIdStructFieldPtr:
case IrInstructionIdUnionFieldPtr:
case IrInstructionIdArrayType:
case IrInstructionIdPromiseType:
case IrInstructionIdSliceType:
@ -25389,6 +25383,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
}
case IrInstructionIdUnwrapErrCode:
return reinterpret_cast<IrInstructionUnwrapErrCode *>(instruction)->initializing;
case IrInstructionIdUnionFieldPtr:
return reinterpret_cast<IrInstructionUnionFieldPtr *>(instruction)->initializing;
case IrInstructionIdErrWrapPayload:
return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr;
case IrInstructionIdErrWrapCode:

View File

@ -1,4 +1,4 @@
// TODO remove `use` keyword eventually
// TODO remove `use` keyword eventually: https://github.com/ziglang/zig/issues/2591
test "zig fmt: change use to usingnamespace" {
try testTransform(
\\use @import("std");
@ -105,7 +105,6 @@ test "zig fmt: linksection" {
}
test "zig fmt: correctly move doc comments on struct fields" {
if (true) return error.SkipZigTest; // TODO
try testTransform(
\\pub const section_64 = extern struct {
\\ sectname: [16]u8, /// name of this section
@ -917,7 +916,6 @@ test "zig fmt: statements with empty line between" {
}
test "zig fmt: ptr deref operator and unwrap optional operator" {
if (true) return error.SkipZigTest; // TODO
try testCanonical(
\\const a = b.*;
\\const a = b.?;
@ -1020,7 +1018,6 @@ test "zig fmt: same-line comment after a statement" {
}
test "zig fmt: same-line comment after var decl in struct" {
if (true) return error.SkipZigTest; // TODO
try testCanonical(
\\pub const vfs_cap_data = extern struct {
\\ const Data = struct {}; // when on disk.
@ -1030,7 +1027,6 @@ test "zig fmt: same-line comment after var decl in struct" {
}
test "zig fmt: same-line comment after field decl" {
if (true) return error.SkipZigTest; // TODO
try testCanonical(
\\pub const dirent = extern struct {
\\ d_name: u8,
@ -1106,7 +1102,6 @@ test "zig fmt: line comments in struct initializer" {
}
test "zig fmt: first line comment in struct initializer" {
if (true) return error.SkipZigTest; // TODO
try testCanonical(
\\pub async fn acquire(self: *Self) HeldLock {
\\ return HeldLock{
@ -1120,7 +1115,6 @@ test "zig fmt: first line comment in struct initializer" {
}
test "zig fmt: doc comments before struct field" {
if (true) return error.SkipZigTest; // TODO
try testCanonical(
\\pub const Allocator = struct {
\\ /// Allocate byte_count bytes and return them in a slice, with the
@ -1218,7 +1212,6 @@ test "zig fmt: comments before switch prong" {
}
test "zig fmt: comments before var decl in struct" {
if (true) return error.SkipZigTest; // TODO
try testCanonical(
\\pub const vfs_cap_data = extern struct {
\\ // All of these are mandated as little endian
@ -1609,7 +1602,6 @@ test "zig fmt: indexing" {
}
test "zig fmt: struct declaration" {
if (true) return error.SkipZigTest; // TODO
try testCanonical(
\\const S = struct {
\\ const Self = @This();
@ -1641,7 +1633,6 @@ test "zig fmt: struct declaration" {
}
test "zig fmt: enum declaration" {
if (true) return error.SkipZigTest; // TODO
try testCanonical(
\\const E = enum {
\\ Ok,
@ -1670,7 +1661,6 @@ test "zig fmt: enum declaration" {
}
test "zig fmt: union declaration" {
if (true) return error.SkipZigTest; // TODO
try testCanonical(
\\const U = union {
\\ Int: u8,

View File

@ -402,3 +402,23 @@ test "comptime union field value equality" {
expect(a0 != a1);
expect(b0 != b1);
}
test "return union init with void payload" {
const S = struct {
fn entry() void {
expect(func().state == State.one);
}
const Outer = union(enum) {
state: State,
};
const State = union(enum) {
one: void,
two: u32,
};
fn func() Outer {
return Outer{ .state = State{ .one = {} }};
}
};
S.entry();
comptime S.entry();
}