| ... | ... | @@ -197,6 +197,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 197 | 197 | static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 198 | 198 | IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node, |
| 199 | 199 | LVal lval, ResultLoc *parent_result_loc); |
| 200 | static void ir_reset_result(ResultLoc *result_loc); |
| 200 | 201 | |
| 201 | 202 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { |
| 202 | 203 | assert(get_src_ptr_type(const_val->type) != nullptr); |
| ... | ... | @@ -3085,10 +3086,11 @@ static IrInstruction *ir_build_save_err_ret_addr(IrBuilder *irb, Scope *scope, A |
| 3085 | 3086 | } |
| 3086 | 3087 | |
| 3087 | 3088 | static IrInstruction *ir_build_add_implicit_return_type(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 3088 | | IrInstruction *value) |
| 3089 | IrInstruction *value, ResultLocReturn *result_loc_ret) |
| 3089 | 3090 | { |
| 3090 | 3091 | IrInstructionAddImplicitReturnType *instruction = ir_build_instruction<IrInstructionAddImplicitReturnType>(irb, scope, source_node); |
| 3091 | 3092 | instruction->value = value; |
| 3093 | instruction->result_loc_ret = result_loc_ret; |
| 3092 | 3094 | |
| 3093 | 3095 | ir_ref_instruction(value, irb->current_basic_block); |
| 3094 | 3096 | |
| ... | ... | @@ -3505,7 +3507,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3505 | 3507 | return_value = ir_build_const_void(irb, scope, node); |
| 3506 | 3508 | } |
| 3507 | 3509 | |
| 3508 | | ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, return_value)); |
| 3510 | ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, return_value, result_loc_ret)); |
| 3509 | 3511 | |
| 3510 | 3512 | size_t defer_counts[2]; |
| 3511 | 3513 | ir_count_defers(irb, scope, outer_scope, defer_counts); |
| ... | ... | @@ -3580,7 +3582,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3580 | 3582 | ir_set_cursor_at_end_and_append_block(irb, return_block); |
| 3581 | 3583 | IrInstruction *err_val_ptr = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr); |
| 3582 | 3584 | IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); |
| 3583 | | ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, err_val)); |
| 3585 | ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, err_val, nullptr)); |
| 3584 | 3586 | IrInstructionSpillBegin *spill_begin = ir_build_spill_begin(irb, scope, node, err_val, |
| 3585 | 3587 | SpillIdRetErrCode); |
| 3586 | 3588 | ResultLocReturn *result_loc_ret = allocate<ResultLocReturn>(1); |
| ... | ... | @@ -3690,6 +3692,7 @@ static ResultLocPeer *create_peer_result(ResultLocPeerParent *peer_parent) { |
| 3690 | 3692 | result->base.id = ResultLocIdPeer; |
| 3691 | 3693 | result->base.source_instruction = peer_parent->base.source_instruction; |
| 3692 | 3694 | result->parent = peer_parent; |
| 3695 | result->base.allow_write_through_const = peer_parent->parent->allow_write_through_const; |
| 3693 | 3696 | return result; |
| 3694 | 3697 | } |
| 3695 | 3698 | |
| ... | ... | @@ -3812,7 +3815,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3812 | 3815 | // no need for save_err_ret_addr because this cannot return error |
| 3813 | 3816 | // only generate unconditional defers |
| 3814 | 3817 | |
| 3815 | | ir_mark_gen(ir_build_add_implicit_return_type(irb, child_scope, block_node, result)); |
| 3818 | ir_mark_gen(ir_build_add_implicit_return_type(irb, child_scope, block_node, result, nullptr)); |
| 3816 | 3819 | ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); |
| 3817 | 3820 | return ir_mark_gen(ir_build_return(irb, child_scope, result->source_node, result)); |
| 3818 | 3821 | } |
| ... | ... | @@ -8207,7 +8210,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec |
| 8207 | 8210 | } |
| 8208 | 8211 | |
| 8209 | 8212 | if (!instr_is_unreachable(result)) { |
| 8210 | | ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, result->source_node, result)); |
| 8213 | ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, result->source_node, result, nullptr)); |
| 8211 | 8214 | // no need for save_err_ret_addr because this cannot return error |
| 8212 | 8215 | ir_mark_gen(ir_build_return(irb, scope, result->source_node, result)); |
| 8213 | 8216 | } |
| ... | ... | @@ -12939,7 +12942,9 @@ static IrInstruction *ir_analyze_instruction_add_implicit_return_type(IrAnalyze |
| 12939 | 12942 | if (type_is_invalid(value->value.type)) |
| 12940 | 12943 | return ir_unreach_error(ira); |
| 12941 | 12944 | |
| 12942 | | ira->src_implicit_return_type_list.append(value); |
| 12945 | if (instruction->result_loc_ret == nullptr || !instruction->result_loc_ret->implicit_return_type_done) { |
| 12946 | ira->src_implicit_return_type_list.append(value); |
| 12947 | } |
| 12943 | 12948 | |
| 12944 | 12949 | return ir_const_void(ira, &instruction->base); |
| 12945 | 12950 | } |
| ... | ... | @@ -14976,6 +14981,24 @@ static void set_up_result_loc_for_inferred_comptime(IrInstruction *ptr) { |
| 14976 | 14981 | ptr->value.data.x_ptr.data.ref.pointee = undef_child; |
| 14977 | 14982 | } |
| 14978 | 14983 | |
| 14984 | static bool ir_result_has_type(ResultLoc *result_loc) { |
| 14985 | switch (result_loc->id) { |
| 14986 | case ResultLocIdInvalid: |
| 14987 | case ResultLocIdPeerParent: |
| 14988 | zig_unreachable(); |
| 14989 | case ResultLocIdNone: |
| 14990 | case ResultLocIdPeer: |
| 14991 | return false; |
| 14992 | case ResultLocIdReturn: |
| 14993 | case ResultLocIdInstruction: |
| 14994 | case ResultLocIdBitCast: |
| 14995 | return true; |
| 14996 | case ResultLocIdVar: |
| 14997 | return reinterpret_cast<ResultLocVar *>(result_loc)->var->decl_node->data.variable_declaration.type != nullptr; |
| 14998 | } |
| 14999 | zig_unreachable(); |
| 15000 | } |
| 15001 | |
| 14979 | 15002 | // when calling this function, at the callsite must check for result type noreturn and propagate it up |
| 14980 | 15003 | static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr, |
| 14981 | 15004 | ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime) |
| ... | ... | @@ -15105,14 +15128,23 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe |
| 15105 | 15128 | bool is_comptime; |
| 15106 | 15129 | if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_comptime)) |
| 15107 | 15130 | return ira->codegen->invalid_instruction; |
| 15108 | | peer_parent->skipped = is_comptime; |
| 15109 | | if (peer_parent->skipped) { |
| 15131 | if (is_comptime) { |
| 15132 | peer_parent->skipped = true; |
| 15110 | 15133 | if (non_null_comptime) { |
| 15111 | 15134 | return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, |
| 15112 | 15135 | value_type, value, force_runtime, non_null_comptime, true); |
| 15113 | 15136 | } |
| 15114 | 15137 | return nullptr; |
| 15115 | 15138 | } |
| 15139 | if (ir_result_has_type(peer_parent->parent)) { |
| 15140 | if (peer_parent->parent->id == ResultLocIdReturn && value != nullptr) { |
| 15141 | reinterpret_cast<ResultLocReturn *>(peer_parent->parent)->implicit_return_type_done = true; |
| 15142 | ira->src_implicit_return_type_list.append(value); |
| 15143 | } |
| 15144 | peer_parent->skipped = true; |
| 15145 | return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, |
| 15146 | value_type, value, force_runtime, true, true); |
| 15147 | } |
| 15116 | 15148 | |
| 15117 | 15149 | if (peer_parent->resolved_type == nullptr) { |
| 15118 | 15150 | if (peer_parent->end_bb->suspend_instruction_ref == nullptr) { |
| ... | ... | @@ -15322,9 +15354,11 @@ static void ir_reset_result(ResultLoc *result_loc) { |
| 15322 | 15354 | alloca_src->base.child = nullptr; |
| 15323 | 15355 | break; |
| 15324 | 15356 | } |
| 15357 | case ResultLocIdReturn: |
| 15358 | reinterpret_cast<ResultLocReturn *>(result_loc)->implicit_return_type_done = false; |
| 15359 | break; |
| 15325 | 15360 | case ResultLocIdPeer: |
| 15326 | 15361 | case ResultLocIdNone: |
| 15327 | | case ResultLocIdReturn: |
| 15328 | 15362 | case ResultLocIdInstruction: |
| 15329 | 15363 | case ResultLocIdBitCast: |
| 15330 | 15364 | break; |
| ... | ... | @@ -16880,10 +16914,21 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 16880 | 16914 | return new_incoming_values.at(0); |
| 16881 | 16915 | } |
| 16882 | 16916 | |
| 16883 | | ZigType *resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.source_node, nullptr, |
| 16884 | | new_incoming_values.items, new_incoming_values.length); |
| 16885 | | if (type_is_invalid(resolved_type)) |
| 16886 | | return ira->codegen->invalid_instruction; |
| 16917 | ZigType *resolved_type; |
| 16918 | if (peer_parent != nullptr && ir_result_has_type(peer_parent->parent)) { |
| 16919 | if (peer_parent->parent->id == ResultLocIdReturn) { |
| 16920 | resolved_type = ira->explicit_return_type; |
| 16921 | } else { |
| 16922 | ZigType *resolved_loc_ptr_type = peer_parent->parent->resolved_loc->value.type; |
| 16923 | ir_assert(resolved_loc_ptr_type->id == ZigTypeIdPointer, &phi_instruction->base); |
| 16924 | resolved_type = resolved_loc_ptr_type->data.pointer.child_type; |
| 16925 | } |
| 16926 | } else { |
| 16927 | resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.source_node, nullptr, |
| 16928 | new_incoming_values.items, new_incoming_values.length); |
| 16929 | if (type_is_invalid(resolved_type)) |
| 16930 | return ira->codegen->invalid_instruction; |
| 16931 | } |
| 16887 | 16932 | |
| 16888 | 16933 | switch (type_has_one_possible_value(ira->codegen, resolved_type)) { |
| 16889 | 16934 | case OnePossibleValueInvalid: |
| ... | ... | @@ -25055,7 +25100,7 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct |
| 25055 | 25100 | if (result_loc->value.type->id == ZigTypeIdUnreachable) |
| 25056 | 25101 | return result_loc; |
| 25057 | 25102 | |
| 25058 | | if (!was_written) { |
| 25103 | if (!was_written || instruction->result_loc->id == ResultLocIdPeer) { |
| 25059 | 25104 | IrInstruction *store_ptr = ir_analyze_store_ptr(ira, &instruction->base, result_loc, value, |
| 25060 | 25105 | instruction->result_loc->allow_write_through_const); |
| 25061 | 25106 | if (type_is_invalid(store_ptr->value.type)) { |
| ... | ... | @@ -25063,7 +25108,9 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct |
| 25063 | 25108 | } |
| 25064 | 25109 | } |
| 25065 | 25110 | |
| 25066 | | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer) { |
| 25111 | if (result_loc->value.data.x_ptr.mut == ConstPtrMutInfer && |
| 25112 | instruction->result_loc->id != ResultLocIdPeer) |
| 25113 | { |
| 25067 | 25114 | if (instr_is_comptime(value)) { |
| 25068 | 25115 | result_loc->value.data.x_ptr.mut = ConstPtrMutComptimeConst; |
| 25069 | 25116 | } else { |