| ... | ... | @@ -193,6 +193,8 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr |
| 193 | 193 | IrInstruction *base_ptr, bool safety_check_on, bool initializing); |
| 194 | 194 | static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| 195 | 195 | IrInstruction *base_ptr, bool safety_check_on, bool initializing); |
| 196 | static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr, |
| 197 | IrInstruction *base_ptr, bool initializing); |
| 196 | 198 | |
| 197 | 199 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { |
| 198 | 200 | assert(get_src_ptr_type(const_val->type) != nullptr); |
| ... | ... | @@ -15016,13 +15018,17 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s |
| 15016 | 15018 | if (actual_elem_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional) { |
| 15017 | 15019 | return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true); |
| 15018 | 15020 | } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion) { |
| 15019 | | IrInstruction *unwrapped_err_ptr = ir_analyze_unwrap_error_payload(ira, suspend_source_instr, |
| 15020 | | result_loc, false, true); |
| 15021 | | ZigType *actual_payload_type = actual_elem_type->data.error_union.payload_type; |
| 15022 | | if (actual_payload_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional) { |
| 15023 | | return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, unwrapped_err_ptr, false, true); |
| 15021 | if (value_type->id == ZigTypeIdErrorSet) { |
| 15022 | return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, true); |
| 15024 | 15023 | } else { |
| 15025 | | return unwrapped_err_ptr; |
| 15024 | IrInstruction *unwrapped_err_ptr = ir_analyze_unwrap_error_payload(ira, suspend_source_instr, |
| 15025 | result_loc, false, true); |
| 15026 | ZigType *actual_payload_type = actual_elem_type->data.error_union.payload_type; |
| 15027 | if (actual_payload_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional) { |
| 15028 | return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, unwrapped_err_ptr, false, true); |
| 15029 | } else { |
| 15030 | return unwrapped_err_ptr; |
| 15031 | } |
| 15026 | 15032 | } |
| 15027 | 15033 | } |
| 15028 | 15034 | return result_loc; |
| ... | ... | @@ -16437,6 +16443,9 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 16437 | 16443 | peer_parent->base.source_instruction->source_node, expected_type, instructions, |
| 16438 | 16444 | peer_parent->peer_count); |
| 16439 | 16445 | |
| 16446 | // the logic below assumes there are no instructions in the new current basic block yet |
| 16447 | ir_assert(ira->new_irb.current_basic_block->instruction_list.length == 0, &phi_instruction->base); |
| 16448 | |
| 16440 | 16449 | // In case resolving the parent activates a suspend, do it now |
| 16441 | 16450 | IrInstruction *parent_result_loc = ir_resolve_result(ira, &phi_instruction->base, peer_parent->parent, |
| 16442 | 16451 | peer_parent->resolved_type, nullptr); |
| ... | ... | @@ -16445,6 +16454,21 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 16445 | 16454 | { |
| 16446 | 16455 | return parent_result_loc; |
| 16447 | 16456 | } |
| 16457 | // If the above code generated any instructions in the current basic block, we need |
| 16458 | // to move them to the peer parent predecessor. |
| 16459 | ZigList<IrInstruction *> instrs_to_move = {}; |
| 16460 | while (ira->new_irb.current_basic_block->instruction_list.length != 0) { |
| 16461 | instrs_to_move.append(ira->new_irb.current_basic_block->instruction_list.pop()); |
| 16462 | } |
| 16463 | if (instrs_to_move.length != 0) { |
| 16464 | IrBasicBlock *predecessor = peer_parent->base.source_instruction->child->owner_bb; |
| 16465 | IrInstruction *branch_instruction = predecessor->instruction_list.pop(); |
| 16466 | ir_assert(branch_instruction->value.type->id == ZigTypeIdUnreachable, &phi_instruction->base); |
| 16467 | while (instrs_to_move.length != 0) { |
| 16468 | predecessor->instruction_list.append(instrs_to_move.pop()); |
| 16469 | } |
| 16470 | predecessor->instruction_list.append(branch_instruction); |
| 16471 | } |
| 16448 | 16472 | } |
| 16449 | 16473 | |
| 16450 | 16474 | IrSuspendPosition suspend_pos; |
| ... | ... | @@ -22213,10 +22237,9 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct |
| 22213 | 22237 | } |
| 22214 | 22238 | } |
| 22215 | 22239 | |
| 22216 | | static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrInstructionUnwrapErrCode *instruction) { |
| 22217 | | IrInstruction *base_ptr = instruction->err_union_ptr->child; |
| 22218 | | if (type_is_invalid(base_ptr->value.type)) |
| 22219 | | return ira->codegen->invalid_instruction; |
| 22240 | static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr, |
| 22241 | IrInstruction *base_ptr, bool initializing) |
| 22242 | { |
| 22220 | 22243 | ZigType *ptr_type = base_ptr->value.type; |
| 22221 | 22244 | |
| 22222 | 22245 | // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. |
| ... | ... | @@ -22238,30 +22261,38 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrI |
| 22238 | 22261 | if (!ptr_val) |
| 22239 | 22262 | return ira->codegen->invalid_instruction; |
| 22240 | 22263 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 22241 | | ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.source_node); |
| 22264 | ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); |
| 22242 | 22265 | if (err_union_val == nullptr) |
| 22243 | 22266 | return ira->codegen->invalid_instruction; |
| 22244 | 22267 | if (err_union_val->special != ConstValSpecialRuntime) { |
| 22245 | 22268 | ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; |
| 22246 | 22269 | assert(err != nullptr); |
| 22247 | 22270 | |
| 22248 | | IrInstruction *err_set_val = ir_const(ira, &instruction->base, |
| 22249 | | type_entry->data.error_union.err_set_type); |
| 22271 | IrInstruction *err_set_val = ir_const(ira, source_instr, type_entry->data.error_union.err_set_type); |
| 22250 | 22272 | err_set_val->value.data.x_err_set = err; |
| 22251 | 22273 | err_set_val->value.parent.id = ConstParentIdErrUnionCode; |
| 22252 | 22274 | err_set_val->value.parent.data.p_err_union_code.err_union_val = err_union_val; |
| 22253 | 22275 | |
| 22254 | | return ir_get_ref(ira, &instruction->base, err_set_val, is_ptr_const, false); |
| 22276 | return ir_get_ref(ira, source_instr, err_set_val, is_ptr_const, false); |
| 22255 | 22277 | } |
| 22256 | 22278 | } |
| 22257 | 22279 | } |
| 22258 | 22280 | |
| 22259 | 22281 | IrInstruction *result = ir_build_unwrap_err_code(&ira->new_irb, |
| 22260 | | instruction->base.scope, instruction->base.source_node, base_ptr); |
| 22282 | source_instr->scope, source_instr->source_node, base_ptr); |
| 22261 | 22283 | result->value.type = get_pointer_to_type(ira->codegen, type_entry->data.error_union.err_set_type, is_ptr_const); |
| 22262 | 22284 | return result; |
| 22263 | 22285 | } |
| 22264 | 22286 | |
| 22287 | static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, |
| 22288 | IrInstructionUnwrapErrCode *instruction) |
| 22289 | { |
| 22290 | IrInstruction *base_ptr = instruction->err_union_ptr->child; |
| 22291 | if (type_is_invalid(base_ptr->value.type)) |
| 22292 | return ira->codegen->invalid_instruction; |
| 22293 | return ir_analyze_unwrap_err_code(ira, &instruction->base, base_ptr, false); |
| 22294 | } |
| 22295 | |
| 22265 | 22296 | static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| 22266 | 22297 | IrInstruction *base_ptr, bool safety_check_on, bool initializing) |
| 22267 | 22298 | { |
| ... | ... | @@ -24783,7 +24814,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 24783 | 24814 | case IrInstructionIdFrameAddress: |
| 24784 | 24815 | case IrInstructionIdHandle: |
| 24785 | 24816 | case IrInstructionIdTestErr: |
| 24786 | | case IrInstructionIdUnwrapErrCode: |
| 24787 | 24817 | case IrInstructionIdFnProto: |
| 24788 | 24818 | case IrInstructionIdTestComptime: |
| 24789 | 24819 | case IrInstructionIdPtrCastSrc: |
| ... | ... | @@ -24846,8 +24876,11 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 24846 | 24876 | { |
| 24847 | 24877 | IrInstructionUnwrapErrPayload *unwrap_err_payload_instruction = |
| 24848 | 24878 | (IrInstructionUnwrapErrPayload *)instruction; |
| 24849 | | return unwrap_err_payload_instruction->safety_check_on; |
| 24879 | return unwrap_err_payload_instruction->safety_check_on || |
| 24880 | unwrap_err_payload_instruction->initializing; |
| 24850 | 24881 | } |
| 24882 | case IrInstructionIdUnwrapErrCode: |
| 24883 | return reinterpret_cast<IrInstructionUnwrapErrCode *>(instruction)->initializing; |
| 24851 | 24884 | case IrInstructionIdErrWrapPayload: |
| 24852 | 24885 | return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr; |
| 24853 | 24886 | case IrInstructionIdErrWrapCode: |