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