| ... | ... | @@ -1555,7 +1555,7 @@ static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, Scope *scop |
| 1555 | 1555 | |
| 1556 | 1556 | ir_ref_instruction(container_type, irb->current_basic_block); |
| 1557 | 1557 | for (size_t i = 0; i < field_count; i += 1) { |
| 1558 | | ir_ref_instruction(fields[i].value, irb->current_basic_block); |
| 1558 | ir_ref_instruction(fields[i].result_loc, irb->current_basic_block); |
| 1559 | 1559 | } |
| 1560 | 1560 | if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); |
| 1561 | 1561 | |
| ... | ... | @@ -5783,7 +5783,6 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A |
| 5783 | 5783 | return expr_value; |
| 5784 | 5784 | |
| 5785 | 5785 | fields[i].name = name; |
| 5786 | | fields[i].value = expr_value; |
| 5787 | 5786 | fields[i].source_node = entry_node; |
| 5788 | 5787 | fields[i].result_loc = field_ptr; |
| 5789 | 5788 | } |
| ... | ... | @@ -17182,69 +17181,89 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ |
| 17182 | 17181 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 17183 | 17182 | source_instr, container_ptr, container_type); |
| 17184 | 17183 | } |
| 17185 | | } else if (bare_type->id == ZigTypeIdEnum) { |
| 17184 | } |
| 17185 | |
| 17186 | if (bare_type->id == ZigTypeIdEnum) { |
| 17186 | 17187 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 17187 | 17188 | source_instr, container_ptr, container_type); |
| 17188 | | } else if (bare_type->id == ZigTypeIdUnion) { |
| 17189 | } |
| 17190 | |
| 17191 | if (bare_type->id == ZigTypeIdUnion) { |
| 17189 | 17192 | bool is_const = container_ptr->value.type->data.pointer.is_const; |
| 17190 | 17193 | bool is_volatile = container_ptr->value.type->data.pointer.is_volatile; |
| 17191 | 17194 | |
| 17192 | 17195 | TypeUnionField *field = find_union_type_field(bare_type, field_name); |
| 17193 | | if (field) { |
| 17194 | | if (instr_is_comptime(container_ptr)) { |
| 17195 | | ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); |
| 17196 | | if (!ptr_val) |
| 17196 | if (field == nullptr) { |
| 17197 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 17198 | source_instr, container_ptr, container_type); |
| 17199 | } |
| 17200 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, |
| 17201 | is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); |
| 17202 | if (instr_is_comptime(container_ptr)) { |
| 17203 | ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); |
| 17204 | if (!ptr_val) |
| 17205 | return ira->codegen->invalid_instruction; |
| 17206 | |
| 17207 | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| 17208 | ConstExprValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 17209 | if (union_val == nullptr) |
| 17210 | return ira->codegen->invalid_instruction; |
| 17211 | if (type_is_invalid(union_val->type)) |
| 17197 | 17212 | return ira->codegen->invalid_instruction; |
| 17198 | 17213 | |
| 17199 | | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| 17200 | | ConstExprValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 17201 | | if (union_val == nullptr) |
| 17202 | | return ira->codegen->invalid_instruction; |
| 17203 | | if (type_is_invalid(union_val->type)) |
| 17204 | | return ira->codegen->invalid_instruction; |
| 17214 | if (initializing) { |
| 17215 | ConstExprValue *payload_val = create_const_vals(1); |
| 17216 | payload_val->special = ConstValSpecialUndef; |
| 17217 | payload_val->type = field->type_entry; |
| 17218 | ConstParent *parent = get_const_val_parent(ira->codegen, payload_val); |
| 17219 | if (parent != nullptr) { |
| 17220 | parent->id = ConstParentIdUnion; |
| 17221 | parent->data.p_union.union_val = union_val; |
| 17222 | } |
| 17205 | 17223 | |
| 17206 | | if (initializing) { |
| 17207 | | bigint_init_bigint(&union_val->data.x_union.tag, &field->enum_field->value); |
| 17208 | | } else { |
| 17209 | | TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag); |
| 17210 | | if (actual_field == nullptr) |
| 17211 | | zig_unreachable(); |
| 17224 | union_val->special = ConstValSpecialStatic; |
| 17225 | bigint_init_bigint(&union_val->data.x_union.tag, &field->enum_field->value); |
| 17226 | union_val->data.x_union.payload = payload_val; |
| 17227 | } else { |
| 17228 | TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag); |
| 17229 | if (actual_field == nullptr) |
| 17230 | zig_unreachable(); |
| 17212 | 17231 | |
| 17213 | | if (field != actual_field) { |
| 17214 | | ir_add_error_node(ira, source_instr->source_node, |
| 17215 | | buf_sprintf("accessing union field '%s' while field '%s' is set", buf_ptr(field_name), |
| 17216 | | buf_ptr(actual_field->name))); |
| 17217 | | return ira->codegen->invalid_instruction; |
| 17218 | | } |
| 17232 | if (field != actual_field) { |
| 17233 | ir_add_error_node(ira, source_instr->source_node, |
| 17234 | buf_sprintf("accessing union field '%s' while field '%s' is set", buf_ptr(field_name), |
| 17235 | buf_ptr(actual_field->name))); |
| 17236 | return ira->codegen->invalid_instruction; |
| 17219 | 17237 | } |
| 17238 | } |
| 17220 | 17239 | |
| 17221 | | ConstExprValue *payload_val = union_val->data.x_union.payload; |
| 17240 | ConstExprValue *payload_val = union_val->data.x_union.payload; |
| 17222 | 17241 | |
| 17223 | | ZigType *field_type = field->type_entry; |
| 17224 | | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, |
| 17225 | | is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); |
| 17226 | 17242 | |
| 17227 | | IrInstruction *result = ir_const(ira, source_instr, ptr_type); |
| 17228 | | ConstExprValue *const_val = &result->value; |
| 17229 | | const_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 17230 | | const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; |
| 17231 | | const_val->data.x_ptr.data.ref.pointee = payload_val; |
| 17232 | | return result; |
| 17243 | IrInstruction *result; |
| 17244 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| 17245 | result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, |
| 17246 | source_instr->source_node, container_ptr, field, initializing); |
| 17247 | result->value.type = ptr_type; |
| 17248 | result->value.special = ConstValSpecialStatic; |
| 17249 | } else { |
| 17250 | result = ir_const(ira, source_instr, ptr_type); |
| 17233 | 17251 | } |
| 17252 | ConstExprValue *const_val = &result->value; |
| 17253 | const_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 17254 | const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; |
| 17255 | const_val->data.x_ptr.data.ref.pointee = payload_val; |
| 17256 | return result; |
| 17234 | 17257 | } |
| 17235 | | |
| 17236 | | IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, |
| 17237 | | source_instr->source_node, container_ptr, field, initializing); |
| 17238 | | result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, |
| 17239 | | PtrLenSingle, 0, 0, 0, false); |
| 17240 | | return result; |
| 17241 | | } else { |
| 17242 | | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 17243 | | source_instr, container_ptr, container_type); |
| 17244 | 17258 | } |
| 17245 | | } else { |
| 17246 | | zig_unreachable(); |
| 17259 | |
| 17260 | IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, |
| 17261 | source_instr->source_node, container_ptr, field, initializing); |
| 17262 | result->value.type = ptr_type; |
| 17263 | return result; |
| 17247 | 17264 | } |
| 17265 | |
| 17266 | zig_unreachable(); |
| 17248 | 17267 | } |
| 17249 | 17268 | |
| 17250 | 17269 | static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, AstNode *source_node) { |
| ... | ... | @@ -18891,12 +18910,12 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI |
| 18891 | 18910 | } |
| 18892 | 18911 | |
| 18893 | 18912 | IrInstructionContainerInitFieldsField *field = &fields[0]; |
| 18894 | | IrInstruction *field_value = field->value->child; |
| 18895 | | if (type_is_invalid(field_value->value.type)) |
| 18913 | IrInstruction *field_result_loc = field->result_loc->child; |
| 18914 | if (type_is_invalid(field_result_loc->value.type)) |
| 18896 | 18915 | return ira->codegen->invalid_instruction; |
| 18897 | 18916 | |
| 18898 | 18917 | TypeUnionField *type_field = find_union_type_field(container_type, field->name); |
| 18899 | | if (!type_field) { |
| 18918 | if (type_field == nullptr) { |
| 18900 | 18919 | ir_add_error_node(ira, field->source_node, |
| 18901 | 18920 | buf_sprintf("no member named '%s' in union '%s'", |
| 18902 | 18921 | buf_ptr(field->name), buf_ptr(&container_type->name))); |
| ... | ... | @@ -18906,33 +18925,26 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI |
| 18906 | 18925 | if (type_is_invalid(type_field->type_entry)) |
| 18907 | 18926 | return ira->codegen->invalid_instruction; |
| 18908 | 18927 | |
| 18909 | | IrInstruction *casted_field_value = ir_implicit_cast(ira, field_value, type_field->type_entry); |
| 18910 | | if (casted_field_value == ira->codegen->invalid_instruction) |
| 18911 | | return ira->codegen->invalid_instruction; |
| 18912 | | |
| 18913 | | if ((err = type_resolve(ira->codegen, casted_field_value->value.type, ResolveStatusZeroBitsKnown))) |
| 18914 | | return ira->codegen->invalid_instruction; |
| 18928 | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 18929 | if (instr_is_comptime(field_result_loc) && |
| 18930 | field_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) |
| 18931 | { |
| 18932 | result_loc->value.data.x_ptr.mut = ConstPtrMutComptimeConst; |
| 18933 | } else { |
| 18934 | result_loc->value.special = ConstValSpecialRuntime; |
| 18935 | } |
| 18936 | } |
| 18915 | 18937 | |
| 18916 | 18938 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) |
| 18917 | 18939 | || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; |
| 18918 | | if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime || |
| 18919 | | !type_has_bits(casted_field_value->value.type)) |
| 18920 | | { |
| 18921 | | ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk); |
| 18922 | | if (!field_val) |
| 18923 | | return ira->codegen->invalid_instruction; |
| 18924 | | |
| 18925 | | IrInstruction *result = ir_const(ira, instruction, container_type); |
| 18926 | | ConstExprValue *out_val = &result->value; |
| 18927 | | out_val->data.x_union.payload = field_val; |
| 18928 | | out_val->data.x_union.tag = type_field->enum_field->value; |
| 18929 | | out_val->parent.id = ConstParentIdUnion; |
| 18930 | | out_val->parent.data.p_union.union_val = out_val; |
| 18931 | 18940 | |
| 18932 | | return result; |
| 18941 | IrInstruction *result = ir_get_deref(ira, instruction, result_loc, nullptr); |
| 18942 | if (is_comptime && !instr_is_comptime(result)) { |
| 18943 | ir_add_error(ira, field->result_loc, |
| 18944 | buf_sprintf("unable to evaluate constant expression")); |
| 18945 | return ira->codegen->invalid_instruction; |
| 18933 | 18946 | } |
| 18934 | | |
| 18935 | | return ir_get_deref(ira, instruction, result_loc, nullptr); |
| 18947 | return result; |
| 18936 | 18948 | } |
| 18937 | 18949 | |
| 18938 | 18950 | static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction, |