| ... | @@ -196,6 +196,8 @@ static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruct | ... | @@ -196,6 +196,8 @@ static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruct |
| 196 | IrInstruction *base_ptr, bool safety_check_on, bool initializing); | 196 | IrInstruction *base_ptr, bool safety_check_on, bool initializing); |
| 197 | static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr, | 197 | static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr, |
| 198 | IrInstruction *base_ptr, bool initializing); | 198 | IrInstruction *base_ptr, bool initializing); |
| | 199 | static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr, |
| | 200 | IrInstruction *ptr, IrInstruction *uncasted_value); |
| 199 | | 201 | |
| 200 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { | 202 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { |
| 201 | assert(get_src_ptr_type(const_val->type) != nullptr); | 203 | assert(get_src_ptr_type(const_val->type) != nullptr); |
| ... | @@ -3363,7 +3365,6 @@ static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_sco | ... | @@ -3363,7 +3365,6 @@ static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_sco |
| 3363 | case ScopeIdSuspend: | 3365 | case ScopeIdSuspend: |
| 3364 | case ScopeIdCompTime: | 3366 | case ScopeIdCompTime: |
| 3365 | case ScopeIdRuntime: | 3367 | case ScopeIdRuntime: |
| 3366 | case ScopeIdElide: | | |
| 3367 | scope = scope->parent; | 3368 | scope = scope->parent; |
| 3368 | continue; | 3369 | continue; |
| 3369 | case ScopeIdDeferExpr: | 3370 | case ScopeIdDeferExpr: |
| ... | @@ -3420,7 +3421,6 @@ static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *o | ... | @@ -3420,7 +3421,6 @@ static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *o |
| 3420 | case ScopeIdSuspend: | 3421 | case ScopeIdSuspend: |
| 3421 | case ScopeIdCompTime: | 3422 | case ScopeIdCompTime: |
| 3422 | case ScopeIdRuntime: | 3423 | case ScopeIdRuntime: |
| 3423 | case ScopeIdElide: | | |
| 3424 | scope = scope->parent; | 3424 | scope = scope->parent; |
| 3425 | continue; | 3425 | continue; |
| 3426 | case ScopeIdDeferExpr: | 3426 | case ScopeIdDeferExpr: |
| ... | @@ -5758,15 +5758,8 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A | ... | @@ -5758,15 +5758,8 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A |
| 5758 | return irb->codegen->invalid_instruction; | 5758 | return irb->codegen->invalid_instruction; |
| 5759 | } | 5759 | } |
| 5760 | | 5760 | |
| 5761 | IrInstruction *container_ptr = nullptr; | 5761 | IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, parent_result_loc, |
| 5762 | if (!ir_should_inline(irb->exec, scope)) { | 5762 | container_type); |
| 5763 | src_assert(parent_result_loc->scope_elide == nullptr, node); | | |
| 5764 | parent_result_loc->scope_elide = create_elide_scope(irb->codegen, node, scope); | | |
| 5765 | | | |
| 5766 | src_assert(parent_result_loc != nullptr, node); | | |
| 5767 | container_ptr = ir_build_resolve_result(irb, &parent_result_loc->scope_elide->base, | | |
| 5768 | node, parent_result_loc, container_type); | | |
| 5769 | } | | |
| 5770 | | 5763 | |
| 5771 | size_t field_count = container_init_expr->entries.length; | 5764 | size_t field_count = container_init_expr->entries.length; |
| 5772 | IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count); | 5765 | IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count); |
| ... | @@ -5777,27 +5770,22 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A | ... | @@ -5777,27 +5770,22 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A |
| 5777 | Buf *name = entry_node->data.struct_val_field.name; | 5770 | Buf *name = entry_node->data.struct_val_field.name; |
| 5778 | AstNode *expr_node = entry_node->data.struct_val_field.expr; | 5771 | AstNode *expr_node = entry_node->data.struct_val_field.expr; |
| 5779 | | 5772 | |
| 5780 | Scope *val_scope = scope; | 5773 | IrInstruction *field_ptr = ir_build_field_ptr(irb, scope, expr_node, container_ptr, name, true); |
| 5781 | ResultLoc *child_result_loc = nullptr; | 5774 | ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1); |
| 5782 | if (container_ptr != nullptr) { | 5775 | result_loc_inst->base.id = ResultLocIdInstruction; |
| 5783 | IrInstruction *field_ptr = ir_build_field_ptr(irb, &parent_result_loc->scope_elide->base, | 5776 | result_loc_inst->base.source_instruction = field_ptr; |
| 5784 | expr_node, container_ptr, name, true); | 5777 | ir_ref_instruction(field_ptr, irb->current_basic_block); |
| 5785 | ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1); | 5778 | ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); |
| 5786 | result_loc_inst->base.id = ResultLocIdInstruction; | | |
| 5787 | result_loc_inst->base.source_instruction = field_ptr; | | |
| 5788 | ir_ref_instruction(field_ptr, irb->current_basic_block); | | |
| 5789 | child_result_loc = &result_loc_inst->base; | | |
| 5790 | val_scope = &parent_result_loc->scope_elide->base; | | |
| 5791 | } | | |
| 5792 | | 5779 | |
| 5793 | IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, val_scope, LValNone, | 5780 | IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, |
| 5794 | child_result_loc); | 5781 | &result_loc_inst->base); |
| 5795 | if (expr_value == irb->codegen->invalid_instruction) | 5782 | if (expr_value == irb->codegen->invalid_instruction) |
| 5796 | return expr_value; | 5783 | return expr_value; |
| 5797 | | 5784 | |
| 5798 | fields[i].name = name; | 5785 | fields[i].name = name; |
| 5799 | fields[i].value = expr_value; | 5786 | fields[i].value = expr_value; |
| 5800 | fields[i].source_node = entry_node; | 5787 | fields[i].source_node = entry_node; |
| | 5788 | fields[i].result_loc = field_ptr; |
| 5801 | } | 5789 | } |
| 5802 | IrInstruction *init_fields = ir_build_container_init_fields(irb, scope, node, container_type, | 5790 | IrInstruction *init_fields = ir_build_container_init_fields(irb, scope, node, container_type, |
| 5803 | field_count, fields, container_ptr); | 5791 | field_count, fields, container_ptr); |
| ... | @@ -5812,36 +5800,23 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A | ... | @@ -5812,36 +5800,23 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A |
| 5812 | container_type = ir_build_array_type(irb, scope, node, item_count_inst, elem_type); | 5800 | container_type = ir_build_array_type(irb, scope, node, item_count_inst, elem_type); |
| 5813 | } | 5801 | } |
| 5814 | | 5802 | |
| 5815 | IrInstruction *container_ptr = nullptr; | 5803 | IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, parent_result_loc, |
| 5816 | if (!ir_should_inline(irb->exec, scope)) { | 5804 | container_type); |
| 5817 | src_assert(parent_result_loc->scope_elide == nullptr, node); | | |
| 5818 | parent_result_loc->scope_elide = create_elide_scope(irb->codegen, node, scope); | | |
| 5819 | | | |
| 5820 | container_ptr = ir_build_resolve_result(irb, &parent_result_loc->scope_elide->base, | | |
| 5821 | node, parent_result_loc, container_type); | | |
| 5822 | } | | |
| 5823 | | 5805 | |
| 5824 | IrInstruction **values = allocate<IrInstruction *>(item_count); | 5806 | IrInstruction **values = allocate<IrInstruction *>(item_count); |
| 5825 | for (size_t i = 0; i < item_count; i += 1) { | 5807 | for (size_t i = 0; i < item_count; i += 1) { |
| 5826 | AstNode *expr_node = container_init_expr->entries.at(i); | 5808 | AstNode *expr_node = container_init_expr->entries.at(i); |
| 5827 | | 5809 | |
| 5828 | ResultLoc *child_result_loc = nullptr; | 5810 | IrInstruction *elem_index = ir_build_const_usize(irb, scope, expr_node, i); |
| 5829 | Scope *val_scope = scope; | 5811 | IrInstruction *elem_ptr = ir_build_elem_ptr(irb, scope, expr_node, container_ptr, elem_index, |
| 5830 | if (container_ptr != nullptr) { | 5812 | false, PtrLenSingle, true); |
| 5831 | IrInstruction *elem_index = ir_build_const_usize(irb, &parent_result_loc->scope_elide->base, | 5813 | ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1); |
| 5832 | expr_node, i); | 5814 | result_loc_inst->base.id = ResultLocIdInstruction; |
| 5833 | IrInstruction *elem_ptr = ir_build_elem_ptr(irb, &parent_result_loc->scope_elide->base, | 5815 | result_loc_inst->base.source_instruction = elem_ptr; |
| 5834 | expr_node, container_ptr, elem_index, false, PtrLenSingle, true); | 5816 | ir_ref_instruction(elem_ptr, irb->current_basic_block); |
| 5835 | ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1); | | |
| 5836 | result_loc_inst->base.id = ResultLocIdInstruction; | | |
| 5837 | result_loc_inst->base.source_instruction = elem_ptr; | | |
| 5838 | ir_ref_instruction(elem_ptr, irb->current_basic_block); | | |
| 5839 | child_result_loc = &result_loc_inst->base; | | |
| 5840 | val_scope = &parent_result_loc->scope_elide->base; | | |
| 5841 | } | | |
| 5842 | | 5817 | |
| 5843 | IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, val_scope, LValNone, | 5818 | IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, |
| 5844 | child_result_loc); | 5819 | &result_loc_inst->base); |
| 5845 | if (expr_value == irb->codegen->invalid_instruction) | 5820 | if (expr_value == irb->codegen->invalid_instruction) |
| 5846 | return expr_value; | 5821 | return expr_value; |
| 5847 | | 5822 | |
| ... | @@ -8651,8 +8626,6 @@ static ConstExprValue *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec | ... | @@ -8651,8 +8626,6 @@ static ConstExprValue *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec |
| 8651 | IrBasicBlock *bb = exec->basic_block_list.at(0); | 8626 | IrBasicBlock *bb = exec->basic_block_list.at(0); |
| 8652 | for (size_t i = 0; i < bb->instruction_list.length; i += 1) { | 8627 | for (size_t i = 0; i < bb->instruction_list.length; i += 1) { |
| 8653 | IrInstruction *instruction = bb->instruction_list.at(i); | 8628 | IrInstruction *instruction = bb->instruction_list.at(i); |
| 8654 | if (scope_is_elided(instruction->scope)) | | |
| 8655 | continue; | | |
| 8656 | if (instruction->id == IrInstructionIdReturn) { | 8629 | if (instruction->id == IrInstructionIdReturn) { |
| 8657 | IrInstructionReturn *ret_inst = (IrInstructionReturn *)instruction; | 8630 | IrInstructionReturn *ret_inst = (IrInstructionReturn *)instruction; |
| 8658 | IrInstruction *value = ret_inst->value; | 8631 | IrInstruction *value = ret_inst->value; |
| ... | @@ -12745,9 +12718,7 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc | ... | @@ -12745,9 +12718,7 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc |
| 12745 | ir_add_error(ira, ptr, buf_sprintf("attempt to dereference undefined value")); | 12718 | ir_add_error(ira, ptr, buf_sprintf("attempt to dereference undefined value")); |
| 12746 | return ira->codegen->invalid_instruction; | 12719 | return ira->codegen->invalid_instruction; |
| 12747 | } | 12720 | } |
| 12748 | if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst || | 12721 | if (ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 12749 | ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) | | |
| 12750 | { | | |
| 12751 | ConstExprValue *pointee = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); | 12722 | ConstExprValue *pointee = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); |
| 12752 | if (pointee->special != ConstValSpecialRuntime) { | 12723 | if (pointee->special != ConstValSpecialRuntime) { |
| 12753 | IrInstruction *result = ir_const(ira, source_instruction, child_type); | 12724 | IrInstruction *result = ir_const(ira, source_instruction, child_type); |
| ... | @@ -14487,7 +14458,25 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, | ... | @@ -14487,7 +14458,25 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 14487 | } | 14458 | } |
| 14488 | | 14459 | |
| 14489 | if (init_val != nullptr && init_val->special != ConstValSpecialRuntime) { | 14460 | if (init_val != nullptr && init_val->special != ConstValSpecialRuntime) { |
| 14490 | if (var->mem_slot_index != SIZE_MAX) { | 14461 | // Resolve ConstPtrMutInfer |
| | 14462 | if (var->gen_is_const) { |
| | 14463 | var_ptr->value.data.x_ptr.mut = ConstPtrMutComptimeConst; |
| | 14464 | } else if (is_comptime_var) { |
| | 14465 | var_ptr->value.data.x_ptr.mut = ConstPtrMutComptimeVar; |
| | 14466 | } else { |
| | 14467 | // we need a runtime ptr but we have a comptime val. |
| | 14468 | // since it's a comptime val there are no instructions for it. |
| | 14469 | // we memcpy the init value here |
| | 14470 | IrInstruction *deref = ir_get_deref(ira, var_ptr, var_ptr, nullptr); |
| | 14471 | // If this assertion trips, something is wrong with the IR instructions, because |
| | 14472 | // we expected the above deref to return a constant value, but it created a runtime |
| | 14473 | // instruction. |
| | 14474 | assert(deref->value.special != ConstValSpecialRuntime); |
| | 14475 | var_ptr->value.special = ConstValSpecialRuntime; |
| | 14476 | ir_analyze_store_ptr(ira, var_ptr, var_ptr, deref); |
| | 14477 | } |
| | 14478 | |
| | 14479 | if (var_ptr->value.special == ConstValSpecialStatic && var->mem_slot_index != SIZE_MAX) { |
| 14491 | assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length); | 14480 | assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length); |
| 14492 | ConstExprValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index); | 14481 | ConstExprValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index); |
| 14493 | copy_const_val(mem_slot, init_val, !is_comptime_var || var->gen_is_const); | 14482 | copy_const_val(mem_slot, init_val, !is_comptime_var || var->gen_is_const); |
| ... | @@ -14818,9 +14807,9 @@ static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_in | ... | @@ -14818,9 +14807,9 @@ static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_in |
| 14818 | pointee->special = ConstValSpecialUndef; | 14807 | pointee->special = ConstValSpecialUndef; |
| 14819 | | 14808 | |
| 14820 | IrInstructionAllocaGen *result = ir_create_alloca_gen(ira, source_inst, align, name_hint); | 14809 | IrInstructionAllocaGen *result = ir_create_alloca_gen(ira, source_inst, align, name_hint); |
| 14821 | result->base.value.special = force_comptime ? ConstValSpecialStatic : ConstValSpecialRuntime; | 14810 | result->base.value.special = ConstValSpecialStatic; |
| 14822 | result->base.value.data.x_ptr.special = ConstPtrSpecialRef; | 14811 | result->base.value.data.x_ptr.special = ConstPtrSpecialRef; |
| 14823 | result->base.value.data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutRuntimeVar; | 14812 | result->base.value.data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutInfer; |
| 14824 | result->base.value.data.x_ptr.data.ref.pointee = pointee; | 14813 | result->base.value.data.x_ptr.data.ref.pointee = pointee; |
| 14825 | | 14814 | |
| 14826 | if ((err = type_resolve(ira->codegen, var_type, ResolveStatusZeroBitsKnown))) | 14815 | if ((err = type_resolve(ira->codegen, var_type, ResolveStatusZeroBitsKnown))) |
| ... | @@ -15109,7 +15098,10 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrIn | ... | @@ -15109,7 +15098,10 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrIn |
| 15109 | ZigType *implicit_elem_type = ir_resolve_type(ira, instruction->ty->child); | 15098 | ZigType *implicit_elem_type = ir_resolve_type(ira, instruction->ty->child); |
| 15110 | if (type_is_invalid(implicit_elem_type)) | 15099 | if (type_is_invalid(implicit_elem_type)) |
| 15111 | return ira->codegen->invalid_instruction; | 15100 | return ira->codegen->invalid_instruction; |
| 15112 | return ir_resolve_result(ira, &instruction->base, instruction->result_loc, implicit_elem_type, nullptr); | 15101 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, implicit_elem_type, nullptr); |
| | 15102 | if (result_loc != nullptr) |
| | 15103 | return result_loc; |
| | 15104 | zig_panic("TODO"); |
| 15113 | } | 15105 | } |
| 15114 | | 15106 | |
| 15115 | static void ir_reset_result(ResultLoc *result_loc) { | 15107 | static void ir_reset_result(ResultLoc *result_loc) { |
| ... | @@ -15431,7 +15423,9 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source | ... | @@ -15431,7 +15423,9 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 15431 | ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); | 15423 | ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); |
| 15432 | return ira->codegen->invalid_instruction; | 15424 | return ira->codegen->invalid_instruction; |
| 15433 | } | 15425 | } |
| 15434 | if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) { | 15426 | if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar || |
| | 15427 | ptr->value.data.x_ptr.mut == ConstPtrMutInfer) |
| | 15428 | { |
| 15435 | if (instr_is_comptime(value)) { | 15429 | if (instr_is_comptime(value)) { |
| 15436 | ConstExprValue *dest_val = const_ptr_pointee(ira, ira->codegen, &ptr->value, source_instr->source_node); | 15430 | ConstExprValue *dest_val = const_ptr_pointee(ira, ira->codegen, &ptr->value, source_instr->source_node); |
| 15437 | if (dest_val == nullptr) | 15431 | if (dest_val == nullptr) |
| ... | @@ -15451,12 +15445,16 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source | ... | @@ -15451,12 +15445,16 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 15451 | return ir_const_void(ira, source_instr); | 15445 | return ir_const_void(ira, source_instr); |
| 15452 | } | 15446 | } |
| 15453 | } | 15447 | } |
| 15454 | ir_add_error(ira, source_instr, | 15448 | if (ptr->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 15455 | buf_sprintf("cannot store runtime value in compile time variable")); | 15449 | ptr->value.special = ConstValSpecialRuntime; |
| 15456 | ConstExprValue *dest_val = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); | 15450 | } else { |
| 15457 | dest_val->type = ira->codegen->builtin_types.entry_invalid; | 15451 | ir_add_error(ira, source_instr, |
| | 15452 | buf_sprintf("cannot store runtime value in compile time variable")); |
| | 15453 | ConstExprValue *dest_val = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); |
| | 15454 | dest_val->type = ira->codegen->builtin_types.entry_invalid; |
| 15458 | | 15455 | |
| 15459 | return ira->codegen->invalid_instruction; | 15456 | return ira->codegen->invalid_instruction; |
| | 15457 | } |
| 15460 | } | 15458 | } |
| 15461 | } | 15459 | } |
| 15462 | | 15460 | |
| ... | @@ -17091,6 +17089,81 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, | ... | @@ -17091,6 +17089,81 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, |
| 17091 | return ira->codegen->invalid_instruction; | 17089 | return ira->codegen->invalid_instruction; |
| 17092 | } | 17090 | } |
| 17093 | | 17091 | |
| | 17092 | static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr, |
| | 17093 | TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing) |
| | 17094 | { |
| | 17095 | switch (type_has_one_possible_value(ira->codegen, field->type_entry)) { |
| | 17096 | case OnePossibleValueInvalid: |
| | 17097 | return ira->codegen->invalid_instruction; |
| | 17098 | case OnePossibleValueYes: { |
| | 17099 | IrInstruction *elem = ir_const(ira, source_instr, field->type_entry); |
| | 17100 | return ir_get_ref(ira, source_instr, elem, false, false); |
| | 17101 | } |
| | 17102 | case OnePossibleValueNo: |
| | 17103 | break; |
| | 17104 | } |
| | 17105 | assert(struct_ptr->value.type->id == ZigTypeIdPointer); |
| | 17106 | bool is_packed = (struct_type->data.structure.layout == ContainerLayoutPacked); |
| | 17107 | uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); |
| | 17108 | uint32_t ptr_bit_offset = struct_ptr->value.type->data.pointer.bit_offset_in_host; |
| | 17109 | uint32_t ptr_host_int_bytes = struct_ptr->value.type->data.pointer.host_int_bytes; |
| | 17110 | uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ? |
| | 17111 | get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes; |
| | 17112 | bool is_const = struct_ptr->value.type->data.pointer.is_const; |
| | 17113 | bool is_volatile = struct_ptr->value.type->data.pointer.is_volatile; |
| | 17114 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, |
| | 17115 | is_const, is_volatile, PtrLenSingle, align_bytes, |
| | 17116 | (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), |
| | 17117 | (uint32_t)host_int_bytes_for_result_type, false); |
| | 17118 | if (instr_is_comptime(struct_ptr)) { |
| | 17119 | ConstExprValue *ptr_val = ir_resolve_const(ira, struct_ptr, UndefBad); |
| | 17120 | if (!ptr_val) |
| | 17121 | return ira->codegen->invalid_instruction; |
| | 17122 | |
| | 17123 | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| | 17124 | ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| | 17125 | if (struct_val == nullptr) |
| | 17126 | return ira->codegen->invalid_instruction; |
| | 17127 | if (type_is_invalid(struct_val->type)) |
| | 17128 | return ira->codegen->invalid_instruction; |
| | 17129 | if (struct_val->special == ConstValSpecialUndef && initializing) { |
| | 17130 | struct_val->data.x_struct.fields = create_const_vals(struct_type->data.structure.src_field_count); |
| | 17131 | struct_val->special = ConstValSpecialStatic; |
| | 17132 | for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) { |
| | 17133 | ConstExprValue *field_val = &struct_val->data.x_struct.fields[i]; |
| | 17134 | field_val->special = ConstValSpecialUndef; |
| | 17135 | field_val->type = struct_type->data.structure.fields[i].type_entry; |
| | 17136 | ConstParent *parent = get_const_val_parent(ira->codegen, field_val); |
| | 17137 | if (parent != nullptr) { |
| | 17138 | parent->id = ConstParentIdStruct; |
| | 17139 | parent->data.p_struct.struct_val = struct_val; |
| | 17140 | parent->data.p_struct.field_index = i; |
| | 17141 | } |
| | 17142 | } |
| | 17143 | } |
| | 17144 | IrInstruction *result; |
| | 17145 | if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { |
| | 17146 | result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, |
| | 17147 | source_instr->source_node, struct_ptr, field); |
| | 17148 | result->value.type = ptr_type; |
| | 17149 | result->value.special = ConstValSpecialStatic; |
| | 17150 | } else { |
| | 17151 | result = ir_const(ira, source_instr, ptr_type); |
| | 17152 | } |
| | 17153 | ConstExprValue *const_val = &result->value; |
| | 17154 | const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct; |
| | 17155 | const_val->data.x_ptr.mut = struct_ptr->value.data.x_ptr.mut; |
| | 17156 | const_val->data.x_ptr.data.base_struct.struct_val = struct_val; |
| | 17157 | const_val->data.x_ptr.data.base_struct.field_index = field->src_index; |
| | 17158 | return result; |
| | 17159 | } |
| | 17160 | } |
| | 17161 | IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, |
| | 17162 | struct_ptr, field); |
| | 17163 | result->value.type = ptr_type; |
| | 17164 | return result; |
| | 17165 | } |
| | 17166 | |
| 17094 | static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, | 17167 | static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, |
| 17095 | IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing) | 17168 | IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing) |
| 17096 | { | 17169 | { |
| ... | @@ -17101,59 +17174,10 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ | ... | @@ -17101,59 +17174,10 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ |
| 17101 | return ira->codegen->invalid_instruction; | 17174 | return ira->codegen->invalid_instruction; |
| 17102 | | 17175 | |
| 17103 | assert(container_ptr->value.type->id == ZigTypeIdPointer); | 17176 | assert(container_ptr->value.type->id == ZigTypeIdPointer); |
| 17104 | bool is_const = container_ptr->value.type->data.pointer.is_const; | | |
| 17105 | bool is_volatile = container_ptr->value.type->data.pointer.is_volatile; | | |
| 17106 | if (bare_type->id == ZigTypeIdStruct) { | 17177 | if (bare_type->id == ZigTypeIdStruct) { |
| 17107 | TypeStructField *field = find_struct_type_field(bare_type, field_name); | 17178 | TypeStructField *field = find_struct_type_field(bare_type, field_name); |
| 17108 | if (field) { | 17179 | if (field != nullptr) { |
| 17109 | switch (type_has_one_possible_value(ira->codegen, field->type_entry)) { | 17180 | return ir_analyze_struct_field_ptr(ira, source_instr, field, container_ptr, bare_type, initializing); |
| 17110 | case OnePossibleValueInvalid: | | |
| 17111 | return ira->codegen->invalid_instruction; | | |
| 17112 | case OnePossibleValueYes: { | | |
| 17113 | IrInstruction *elem = ir_const(ira, source_instr, field->type_entry); | | |
| 17114 | return ir_get_ref(ira, source_instr, elem, false, false); | | |
| 17115 | } | | |
| 17116 | case OnePossibleValueNo: | | |
| 17117 | break; | | |
| 17118 | } | | |
| 17119 | bool is_packed = (bare_type->data.structure.layout == ContainerLayoutPacked); | | |
| 17120 | uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); | | |
| 17121 | uint32_t ptr_bit_offset = container_ptr->value.type->data.pointer.bit_offset_in_host; | | |
| 17122 | uint32_t ptr_host_int_bytes = container_ptr->value.type->data.pointer.host_int_bytes; | | |
| 17123 | uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ? | | |
| 17124 | get_host_int_bytes(ira->codegen, bare_type, field) : ptr_host_int_bytes; | | |
| 17125 | if (instr_is_comptime(container_ptr)) { | | |
| 17126 | ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); | | |
| 17127 | if (!ptr_val) | | |
| 17128 | return ira->codegen->invalid_instruction; | | |
| 17129 | | | |
| 17130 | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { | | |
| 17131 | ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); | | |
| 17132 | if (struct_val == nullptr) | | |
| 17133 | return ira->codegen->invalid_instruction; | | |
| 17134 | if (type_is_invalid(struct_val->type)) | | |
| 17135 | return ira->codegen->invalid_instruction; | | |
| 17136 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, | | |
| 17137 | is_const, is_volatile, PtrLenSingle, align_bytes, | | |
| 17138 | (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), | | |
| 17139 | (uint32_t)host_int_bytes_for_result_type, false); | | |
| 17140 | IrInstruction *result = ir_const(ira, source_instr, ptr_type); | | |
| 17141 | ConstExprValue *const_val = &result->value; | | |
| 17142 | const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct; | | |
| 17143 | const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; | | |
| 17144 | const_val->data.x_ptr.data.base_struct.struct_val = struct_val; | | |
| 17145 | const_val->data.x_ptr.data.base_struct.field_index = field->src_index; | | |
| 17146 | return result; | | |
| 17147 | } | | |
| 17148 | } | | |
| 17149 | IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, | | |
| 17150 | container_ptr, field); | | |
| 17151 | result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, | | |
| 17152 | PtrLenSingle, | | |
| 17153 | align_bytes, | | |
| 17154 | (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), | | |
| 17155 | host_int_bytes_for_result_type, false); | | |
| 17156 | return result; | | |
| 17157 | } else { | 17181 | } else { |
| 17158 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, | 17182 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 17159 | source_instr, container_ptr, container_type); | 17183 | source_instr, container_ptr, container_type); |
| ... | @@ -17162,6 +17186,9 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ | ... | @@ -17162,6 +17186,9 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ |
| 17162 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, | 17186 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |
| 17163 | source_instr, container_ptr, container_type); | 17187 | source_instr, container_ptr, container_type); |
| 17164 | } else if (bare_type->id == ZigTypeIdUnion) { | 17188 | } else if (bare_type->id == ZigTypeIdUnion) { |
| | 17189 | bool is_const = container_ptr->value.type->data.pointer.is_const; |
| | 17190 | bool is_volatile = container_ptr->value.type->data.pointer.is_volatile; |
| | 17191 | |
| 17165 | TypeUnionField *field = find_union_type_field(bare_type, field_name); | 17192 | TypeUnionField *field = find_union_type_field(bare_type, field_name); |
| 17166 | if (field) { | 17193 | if (field) { |
| 17167 | if (instr_is_comptime(container_ptr)) { | 17194 | if (instr_is_comptime(container_ptr)) { |
| ... | @@ -18849,7 +18876,7 @@ static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRe | ... | @@ -18849,7 +18876,7 @@ static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRe |
| 18849 | | 18876 | |
| 18850 | static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrInstruction *instruction, | 18877 | static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrInstruction *instruction, |
| 18851 | ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields, | 18878 | ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields, |
| 18852 | IrInstruction *old_result_loc) | 18879 | IrInstruction *result_loc) |
| 18853 | { | 18880 | { |
| 18854 | Error err; | 18881 | Error err; |
| 18855 | assert(container_type->id == ZigTypeIdUnion); | 18882 | assert(container_type->id == ZigTypeIdUnion); |
| ... | @@ -18905,21 +18932,17 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI | ... | @@ -18905,21 +18932,17 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI |
| 18905 | return result; | 18932 | return result; |
| 18906 | } | 18933 | } |
| 18907 | | 18934 | |
| 18908 | ir_assert(old_result_loc != nullptr, instruction); | | |
| 18909 | IrInstruction *result_loc = old_result_loc->child; | | |
| 18910 | if (type_is_invalid(result_loc->value.type)) | | |
| 18911 | return result_loc; | | |
| 18912 | return ir_get_deref(ira, instruction, result_loc, nullptr); | 18935 | return ir_get_deref(ira, instruction, result_loc, nullptr); |
| 18913 | } | 18936 | } |
| 18914 | | 18937 | |
| 18915 | static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction, | 18938 | static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction, |
| 18916 | ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields, | 18939 | ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields, |
| 18917 | IrInstruction *old_result_loc) | 18940 | IrInstruction *result_loc) |
| 18918 | { | 18941 | { |
| 18919 | Error err; | 18942 | Error err; |
| 18920 | if (container_type->id == ZigTypeIdUnion) { | 18943 | if (container_type->id == ZigTypeIdUnion) { |
| 18921 | return ir_analyze_container_init_fields_union(ira, instruction, container_type, instr_field_count, | 18944 | return ir_analyze_container_init_fields_union(ira, instruction, container_type, instr_field_count, |
| 18922 | fields, old_result_loc); | 18945 | fields, result_loc); |
| 18923 | } | 18946 | } |
| 18924 | if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) { | 18947 | if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) { |
| 18925 | ir_add_error(ira, instruction, | 18948 | ir_add_error(ira, instruction, |
| ... | @@ -18936,20 +18959,28 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc | ... | @@ -18936,20 +18959,28 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 18936 | IrInstruction *first_non_const_instruction = nullptr; | 18959 | IrInstruction *first_non_const_instruction = nullptr; |
| 18937 | | 18960 | |
| 18938 | AstNode **field_assign_nodes = allocate<AstNode *>(actual_field_count); | 18961 | AstNode **field_assign_nodes = allocate<AstNode *>(actual_field_count); |
| | 18962 | ZigList<IrInstruction *> const_ptrs = {}; |
| 18939 | | 18963 | |
| 18940 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) | 18964 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) |
| 18941 | || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; | 18965 | || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; |
| 18942 | | 18966 | |
| 18943 | ConstExprValue const_val = {}; | 18967 | |
| 18944 | const_val.special = ConstValSpecialStatic; | 18968 | // Here we iterate over the fields that have been initialized, and emit |
| 18945 | const_val.type = container_type; | 18969 | // compile errors for missing fields and duplicate fields. |
| 18946 | // const_val.global_refs = allocate<ConstGlobalRefs>(1); | 18970 | // It is only now that we find out whether the struct initialization can be a comptime |
| 18947 | const_val.data.x_struct.fields = create_const_vals(actual_field_count); | 18971 | // value, but we have already emitted runtime instructions for the fields that |
| | 18972 | // were initialized with runtime values, and have omitted instructions that would have |
| | 18973 | // initialized fields with comptime values. |
| | 18974 | // So now we must clean up this situation. If it turns out the struct initialization can |
| | 18975 | // be a comptime value, overwrite ConstPtrMutInfer with ConstPtrMutComptimeConst. |
| | 18976 | // Otherwise, we must emit instructions to runtime-initialize the fields that have |
| | 18977 | // comptime-known values. |
| | 18978 | |
| 18948 | for (size_t i = 0; i < instr_field_count; i += 1) { | 18979 | for (size_t i = 0; i < instr_field_count; i += 1) { |
| 18949 | IrInstructionContainerInitFieldsField *field = &fields[i]; | 18980 | IrInstructionContainerInitFieldsField *field = &fields[i]; |
| 18950 | | 18981 | |
| 18951 | IrInstruction *field_value = field->value->child; | 18982 | IrInstruction *field_result_loc = field->result_loc->child; |
| 18952 | if (type_is_invalid(field_value->value.type)) | 18983 | if (type_is_invalid(field_result_loc->value.type)) |
| 18953 | return ira->codegen->invalid_instruction; | 18984 | return ira->codegen->invalid_instruction; |
| 18954 | | 18985 | |
| 18955 | TypeStructField *type_field = find_struct_type_field(container_type, field->name); | 18986 | TypeStructField *type_field = find_struct_type_field(container_type, field->name); |
| ... | @@ -18963,10 +18994,6 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc | ... | @@ -18963,10 +18994,6 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 18963 | if (type_is_invalid(type_field->type_entry)) | 18994 | if (type_is_invalid(type_field->type_entry)) |
| 18964 | return ira->codegen->invalid_instruction; | 18995 | return ira->codegen->invalid_instruction; |
| 18965 | | 18996 | |
| 18966 | IrInstruction *casted_field_value = ir_implicit_cast(ira, field_value, type_field->type_entry); | | |
| 18967 | if (casted_field_value == ira->codegen->invalid_instruction) | | |
| 18968 | return ira->codegen->invalid_instruction; | | |
| 18969 | | | |
| 18970 | size_t field_index = type_field->src_index; | 18997 | size_t field_index = type_field->src_index; |
| 18971 | AstNode *existing_assign_node = field_assign_nodes[field_index]; | 18998 | AstNode *existing_assign_node = field_assign_nodes[field_index]; |
| 18972 | if (existing_assign_node) { | 18999 | if (existing_assign_node) { |
| ... | @@ -18976,23 +19003,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc | ... | @@ -18976,23 +19003,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 18976 | } | 19003 | } |
| 18977 | field_assign_nodes[field_index] = field->source_node; | 19004 | field_assign_nodes[field_index] = field->source_node; |
| 18978 | | 19005 | |
| 18979 | if (const_val.special == ConstValSpecialStatic) { | 19006 | if (instr_is_comptime(field_result_loc) && |
| 18980 | if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime) { | 19007 | field_result_loc->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) |
| 18981 | ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk); | 19008 | { |
| 18982 | if (!field_val) | 19009 | const_ptrs.append(field_result_loc); |
| 18983 | return ira->codegen->invalid_instruction; | 19010 | } else { |
| 18984 | | 19011 | first_non_const_instruction = field_result_loc; |
| 18985 | copy_const_val(&const_val.data.x_struct.fields[field_index], field_val, true); | | |
| 18986 | } else { | | |
| 18987 | first_non_const_instruction = casted_field_value; | | |
| 18988 | const_val.special = ConstValSpecialRuntime; | | |
| 18989 | } | | |
| 18990 | } | 19012 | } |
| 18991 | } | 19013 | } |
| 18992 | | 19014 | |
| 18993 | bool any_missing = false; | 19015 | bool any_missing = false; |
| 18994 | for (size_t i = 0; i < actual_field_count; i += 1) { | 19016 | for (size_t i = 0; i < actual_field_count; i += 1) { |
| 18995 | if (field_assign_nodes[i]) continue; | 19017 | if (field_assign_nodes[i] != nullptr) continue; |
| 18996 | | 19018 | |
| 18997 | // look for a default field value | 19019 | // look for a default field value |
| 18998 | TypeStructField *field = &container_type->data.structure.fields[i]; | 19020 | TypeStructField *field = &container_type->data.structure.fields[i]; |
| ... | @@ -19018,44 +19040,41 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc | ... | @@ -19018,44 +19040,41 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 19018 | IrInstruction *runtime_inst = ir_const(ira, instruction, field->init_val->type); | 19040 | IrInstruction *runtime_inst = ir_const(ira, instruction, field->init_val->type); |
| 19019 | copy_const_val(&runtime_inst->value, field->init_val, true); | 19041 | copy_const_val(&runtime_inst->value, field->init_val, true); |
| 19020 | | 19042 | |
| 19021 | if (const_val.special == ConstValSpecialStatic) { | 19043 | IrInstruction *field_ptr = ir_analyze_struct_field_ptr(ira, instruction, field, result_loc, |
| 19022 | copy_const_val(&const_val.data.x_struct.fields[i], field->init_val, true); | 19044 | container_type, true); |
| | 19045 | ir_analyze_store_ptr(ira, instruction, field_ptr, runtime_inst); |
| | 19046 | if (instr_is_comptime(field_ptr) && field_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| | 19047 | const_ptrs.append(field_ptr); |
| | 19048 | } else { |
| | 19049 | first_non_const_instruction = result_loc; |
| 19023 | } | 19050 | } |
| 19024 | } | 19051 | } |
| 19025 | if (any_missing) | 19052 | if (any_missing) |
| 19026 | return ira->codegen->invalid_instruction; | 19053 | return ira->codegen->invalid_instruction; |
| 19027 | | 19054 | |
| 19028 | if (const_val.special == ConstValSpecialStatic) { | 19055 | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 19029 | IrInstruction *result = ir_const(ira, instruction, nullptr); | 19056 | if (const_ptrs.length == actual_field_count) { |
| 19030 | ConstExprValue *out_val = &result->value; | 19057 | result_loc->value.data.x_ptr.mut = ConstPtrMutComptimeConst; |
| 19031 | copy_const_val(out_val, &const_val, false); | 19058 | } else { |
| 19032 | out_val->type = container_type; | 19059 | result_loc->value.special = ConstValSpecialRuntime; |
| 19033 | | 19060 | for (size_t i = 0; i < const_ptrs.length; i += 1) { |
| 19034 | for (size_t i = 0; i < instr_field_count; i += 1) { | 19061 | IrInstruction *field_result_loc = const_ptrs.at(i); |
| 19035 | ConstExprValue *field_val = &out_val->data.x_struct.fields[i]; | 19062 | IrInstruction *deref = ir_get_deref(ira, field_result_loc, field_result_loc, nullptr); |
| 19036 | ConstParent *parent = get_const_val_parent(ira->codegen, field_val); | 19063 | field_result_loc->value.special = ConstValSpecialRuntime; |
| 19037 | if (parent != nullptr) { | 19064 | ir_analyze_store_ptr(ira, field_result_loc, field_result_loc, deref); |
| 19038 | parent->id = ConstParentIdStruct; | | |
| 19039 | parent->data.p_struct.field_index = i; | | |
| 19040 | parent->data.p_struct.struct_val = out_val; | | |
| 19041 | } | 19065 | } |
| 19042 | } | 19066 | } |
| 19043 | | | |
| 19044 | return result; | | |
| 19045 | } | 19067 | } |
| 19046 | | 19068 | |
| 19047 | if (is_comptime) { | 19069 | IrInstruction *result = ir_get_deref(ira, instruction, result_loc, nullptr); |
| | 19070 | |
| | 19071 | if (is_comptime && !instr_is_comptime(result)) { |
| 19048 | ir_add_error_node(ira, first_non_const_instruction->source_node, | 19072 | ir_add_error_node(ira, first_non_const_instruction->source_node, |
| 19049 | buf_sprintf("unable to evaluate constant expression")); | 19073 | buf_sprintf("unable to evaluate constant expression")); |
| 19050 | return ira->codegen->invalid_instruction; | 19074 | return ira->codegen->invalid_instruction; |
| 19051 | } | 19075 | } |
| 19052 | | 19076 | |
| 19053 | | 19077 | return result; |
| 19054 | ir_assert(old_result_loc != nullptr, instruction); | | |
| 19055 | IrInstruction *result_loc = old_result_loc->child; | | |
| 19056 | if (type_is_invalid(result_loc->value.type)) | | |
| 19057 | return result_loc; | | |
| 19058 | return ir_get_deref(ira, instruction, result_loc, nullptr); | | |
| 19059 | } | 19078 | } |
| 19060 | | 19079 | |
| 19061 | static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, | 19080 | static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, |
| ... | @@ -19074,8 +19093,11 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, | ... | @@ -19074,8 +19093,11 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, |
| 19074 | buf_sprintf("expected array type or [_], found slice")); | 19093 | buf_sprintf("expected array type or [_], found slice")); |
| 19075 | return ira->codegen->invalid_instruction; | 19094 | return ira->codegen->invalid_instruction; |
| 19076 | } else if (container_type->id == ZigTypeIdStruct && !is_slice(container_type) && elem_count == 0) { | 19095 | } else if (container_type->id == ZigTypeIdStruct && !is_slice(container_type) && elem_count == 0) { |
| 19077 | return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 0, nullptr, | 19096 | ir_assert(instruction->result_loc != nullptr, &instruction->base); |
| 19078 | instruction->result_loc); | 19097 | IrInstruction *result_loc = instruction->result_loc->child; |
| | 19098 | if (type_is_invalid(result_loc->value.type)) |
| | 19099 | return result_loc; |
| | 19100 | return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 0, nullptr, result_loc); |
| 19079 | } else if (container_type->id == ZigTypeIdArray) { | 19101 | } else if (container_type->id == ZigTypeIdArray) { |
| 19080 | // array is same as slice init but we make a compile error if the length is wrong | 19102 | // array is same as slice init but we make a compile error if the length is wrong |
| 19081 | ZigType *child_type; | 19103 | ZigType *child_type; |
| ... | @@ -19199,8 +19221,13 @@ static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ir | ... | @@ -19199,8 +19221,13 @@ static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ir |
| 19199 | if (type_is_invalid(container_type)) | 19221 | if (type_is_invalid(container_type)) |
| 19200 | return ira->codegen->invalid_instruction; | 19222 | return ira->codegen->invalid_instruction; |
| 19201 | | 19223 | |
| | 19224 | ir_assert(instruction->result_loc != nullptr, &instruction->base); |
| | 19225 | IrInstruction *result_loc = instruction->result_loc->child; |
| | 19226 | if (type_is_invalid(result_loc->value.type)) |
| | 19227 | return result_loc; |
| | 19228 | |
| 19202 | return ir_analyze_container_init_fields(ira, &instruction->base, container_type, | 19229 | return ir_analyze_container_init_fields(ira, &instruction->base, container_type, |
| 19203 | instruction->field_count, instruction->fields, instruction->result_loc); | 19230 | instruction->field_count, instruction->fields, result_loc); |
| 19204 | } | 19231 | } |
| 19205 | | 19232 | |
| 19206 | static IrInstruction *ir_analyze_instruction_compile_err(IrAnalyze *ira, | 19233 | static IrInstruction *ir_analyze_instruction_compile_err(IrAnalyze *ira, |
| ... | @@ -24390,17 +24417,7 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct | ... | @@ -24390,17 +24417,7 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct |
| 24390 | if (type_is_invalid(value->value.type)) | 24417 | if (type_is_invalid(value->value.type)) |
| 24391 | return ira->codegen->invalid_instruction; | 24418 | return ira->codegen->invalid_instruction; |
| 24392 | | 24419 | |
| 24393 | bool want_resolve_result; | 24420 | bool want_resolve_result = !instruction->result_loc->written; |
| 24394 | if (instruction->result_loc->written) { | | |
| 24395 | if (instruction->result_loc->scope_elide != nullptr && instr_is_comptime(value)) { | | |
| 24396 | want_resolve_result = true; | | |
| 24397 | instruction->result_loc->scope_elide->activated = true; | | |
| 24398 | } else { | | |
| 24399 | want_resolve_result = false; | | |
| 24400 | } | | |
| 24401 | } else { | | |
| 24402 | want_resolve_result = true; | | |
| 24403 | } | | |
| 24404 | if (want_resolve_result) { | 24421 | if (want_resolve_result) { |
| 24405 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, | 24422 | IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc, |
| 24406 | value->value.type, value); | 24423 | value->value.type, value); |