| ... | @@ -193,6 +193,8 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr | ... | @@ -193,6 +193,8 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr |
| 193 | IrInstruction *base_ptr, bool safety_check_on, bool initializing); | 193 | IrInstruction *base_ptr, bool safety_check_on, bool initializing); |
| 194 | static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr, | 194 | static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| 195 | IrInstruction *base_ptr, bool safety_check_on, bool initializing); | 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 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { | 199 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { |
| 198 | assert(get_src_ptr_type(const_val->type) != nullptr); | 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,13 +15018,17 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s |
| 15016 | if (actual_elem_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional) { | 15018 | if (actual_elem_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional) { |
| 15017 | return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true); | 15019 | return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true); |
| 15018 | } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion) { | 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, | 15021 | if (value_type->id == ZigTypeIdErrorSet) { |
| 15020 | result_loc, false, true); | 15022 | return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, 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); | | |
| 15024 | } else { | 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 | return result_loc; | 15034 | return result_loc; |
| ... | @@ -16437,6 +16443,9 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh | ... | @@ -16437,6 +16443,9 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 16437 | peer_parent->base.source_instruction->source_node, expected_type, instructions, | 16443 | peer_parent->base.source_instruction->source_node, expected_type, instructions, |
| 16438 | peer_parent->peer_count); | 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 | // In case resolving the parent activates a suspend, do it now | 16449 | // In case resolving the parent activates a suspend, do it now |
| 16441 | IrInstruction *parent_result_loc = ir_resolve_result(ira, &phi_instruction->base, peer_parent->parent, | 16450 | IrInstruction *parent_result_loc = ir_resolve_result(ira, &phi_instruction->base, peer_parent->parent, |
| 16442 | peer_parent->resolved_type, nullptr); | 16451 | peer_parent->resolved_type, nullptr); |
| ... | @@ -16445,6 +16454,21 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh | ... | @@ -16445,6 +16454,21 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 16445 | { | 16454 | { |
| 16446 | return parent_result_loc; | 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 | IrSuspendPosition suspend_pos; | 16474 | IrSuspendPosition suspend_pos; |
| ... | @@ -22213,10 +22237,9 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct | ... | @@ -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) { | 22240 | static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr, |
| 22217 | IrInstruction *base_ptr = instruction->err_union_ptr->child; | 22241 | IrInstruction *base_ptr, bool initializing) |
| 22218 | if (type_is_invalid(base_ptr->value.type)) | 22242 | { |
| 22219 | return ira->codegen->invalid_instruction; | | |
| 22220 | ZigType *ptr_type = base_ptr->value.type; | 22243 | ZigType *ptr_type = base_ptr->value.type; |
| 22221 | | 22244 | |
| 22222 | // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. | 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,30 +22261,38 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrI |
| 22238 | if (!ptr_val) | 22261 | if (!ptr_val) |
| 22239 | return ira->codegen->invalid_instruction; | 22262 | return ira->codegen->invalid_instruction; |
| 22240 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { | 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 | if (err_union_val == nullptr) | 22265 | if (err_union_val == nullptr) |
| 22243 | return ira->codegen->invalid_instruction; | 22266 | return ira->codegen->invalid_instruction; |
| 22244 | if (err_union_val->special != ConstValSpecialRuntime) { | 22267 | if (err_union_val->special != ConstValSpecialRuntime) { |
| 22245 | ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; | 22268 | ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; |
| 22246 | assert(err != nullptr); | 22269 | assert(err != nullptr); |
| 22247 | | 22270 | |
| 22248 | IrInstruction *err_set_val = ir_const(ira, &instruction->base, | 22271 | IrInstruction *err_set_val = ir_const(ira, source_instr, type_entry->data.error_union.err_set_type); |
| 22249 | type_entry->data.error_union.err_set_type); | | |
| 22250 | err_set_val->value.data.x_err_set = err; | 22272 | err_set_val->value.data.x_err_set = err; |
| 22251 | err_set_val->value.parent.id = ConstParentIdErrUnionCode; | 22273 | err_set_val->value.parent.id = ConstParentIdErrUnionCode; |
| 22252 | err_set_val->value.parent.data.p_err_union_code.err_union_val = err_union_val; | 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 | IrInstruction *result = ir_build_unwrap_err_code(&ira->new_irb, | 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 | result->value.type = get_pointer_to_type(ira->codegen, type_entry->data.error_union.err_set_type, is_ptr_const); | 22283 | result->value.type = get_pointer_to_type(ira->codegen, type_entry->data.error_union.err_set_type, is_ptr_const); |
| 22262 | return result; | 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 | static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr, | 22296 | static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr, |
| 22266 | IrInstruction *base_ptr, bool safety_check_on, bool initializing) | 22297 | IrInstruction *base_ptr, bool safety_check_on, bool initializing) |
| 22267 | { | 22298 | { |
| ... | @@ -24783,7 +24814,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -24783,7 +24814,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 24783 | case IrInstructionIdFrameAddress: | 24814 | case IrInstructionIdFrameAddress: |
| 24784 | case IrInstructionIdHandle: | 24815 | case IrInstructionIdHandle: |
| 24785 | case IrInstructionIdTestErr: | 24816 | case IrInstructionIdTestErr: |
| 24786 | case IrInstructionIdUnwrapErrCode: | | |
| 24787 | case IrInstructionIdFnProto: | 24817 | case IrInstructionIdFnProto: |
| 24788 | case IrInstructionIdTestComptime: | 24818 | case IrInstructionIdTestComptime: |
| 24789 | case IrInstructionIdPtrCastSrc: | 24819 | case IrInstructionIdPtrCastSrc: |
| ... | @@ -24846,8 +24876,11 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -24846,8 +24876,11 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 24846 | { | 24876 | { |
| 24847 | IrInstructionUnwrapErrPayload *unwrap_err_payload_instruction = | 24877 | IrInstructionUnwrapErrPayload *unwrap_err_payload_instruction = |
| 24848 | (IrInstructionUnwrapErrPayload *)instruction; | 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 | case IrInstructionIdErrWrapPayload: | 24884 | case IrInstructionIdErrWrapPayload: |
| 24852 | return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr; | 24885 | return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr; |
| 24853 | case IrInstructionIdErrWrapCode: | 24886 | case IrInstructionIdErrWrapCode: |