aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ir.cpp62
1 files changed, 30 insertions, 32 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index a8771285f6..7d5a5305b1 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -10560,22 +10560,33 @@ static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *so
assert(union_field != nullptr);
if ((err = type_resolve(ira->codegen, union_field->type_entry, ResolveStatusZeroBitsKnown)))
return ira->codegen->invalid_instruction;
- if (type_has_bits(union_field->type_entry)) {
- AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at(
- union_field->enum_field->decl_index);
- ErrorMsg *msg = ir_add_error(ira, source_instr,
- buf_sprintf("cast to union '%s' must initialize '%s' field '%s'",
- buf_ptr(&wanted_type->name),
- buf_ptr(&union_field->type_entry->name),
- buf_ptr(union_field->name)));
- add_error_note(ira->codegen, msg, field_node,
- buf_sprintf("field '%s' declared here", buf_ptr(union_field->name)));
- return ira->codegen->invalid_instruction;
+
+ switch (type_has_one_possible_value(ira->codegen, union_field->type_entry)) {
+ case OnePossibleValueInvalid:
+ return ira->codegen->invalid_instruction;
+ case OnePossibleValueNo: {
+ AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at(
+ union_field->enum_field->decl_index);
+ ErrorMsg *msg = ir_add_error(ira, source_instr,
+ buf_sprintf("cast to union '%s' must initialize '%s' field '%s'",
+ buf_ptr(&wanted_type->name),
+ buf_ptr(&union_field->type_entry->name),
+ buf_ptr(union_field->name)));
+ add_error_note(ira->codegen, msg, field_node,
+ buf_sprintf("field '%s' declared here", buf_ptr(union_field->name)));
+ return ira->codegen->invalid_instruction;
+ }
+ case OnePossibleValueYes:
+ break;
}
+
IrInstruction *result = ir_const(ira, source_instr, wanted_type);
result->value.special = ConstValSpecialStatic;
result->value.type = wanted_type;
bigint_init_bigint(&result->value.data.x_union.tag, &val->data.x_enum_tag);
+ result->value.data.x_union.payload = create_const_vals(1);
+ result->value.data.x_union.payload->special = ConstValSpecialStatic;
+ result->value.data.x_union.payload->type = union_field->type_entry;
return result;
}
@@ -15506,13 +15517,6 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
ConstExprValue *payload_val = union_val->data.x_union.payload;
ZigType *field_type = field->type_entry;
- if (field_type->id == ZigTypeIdVoid) {
- assert(payload_val == nullptr);
- payload_val = create_const_vals(1);
- payload_val->special = ConstValSpecialStatic;
- payload_val->type = field_type;
- }
-
ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type,
is_const, is_volatile, PtrLenSingle, 0, 0, 0);
@@ -18038,6 +18042,12 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown)))
return err;
+ auto entry = ira->codegen->type_info_cache.maybe_get(type_entry);
+ if (entry != nullptr) {
+ *out = entry->value;
+ return ErrorNone;
+ }
+
ConstExprValue *result = nullptr;
switch (type_entry->id) {
case ZigTypeIdInvalid:
@@ -18052,19 +18062,8 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
case ZigTypeIdNull:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
- *out = nullptr;
- return ErrorNone;
- default:
- {
- // Lookup an available value in our cache.
- auto entry = ira->codegen->type_info_cache.maybe_get(type_entry);
- if (entry != nullptr) {
- *out = entry->value;
- return ErrorNone;
- }
-
- // Fallthrough if we don't find one.
- }
+ result = &ira->codegen->const_void_val;
+ break;
case ZigTypeIdInt:
{
result = create_const_vals(1);
@@ -18636,7 +18635,6 @@ static IrInstruction *ir_analyze_instruction_type_info(IrAnalyze *ira,
out_val->data.x_union.payload = payload;
if (payload != nullptr) {
- assert(payload->type->id == ZigTypeIdStruct);
payload->parent.id = ConstParentIdUnion;
payload->parent.data.p_union.union_val = out_val;
}