diff --git a/BRANCH_TODO b/BRANCH_TODO index e744162fa..f6fd78dba 100644 --- a/BRANCH_TODO +++ b/BRANCH_TODO @@ -6,17 +6,5 @@ look at all the ir_gen_node ir_gen_node_extra calls and make sure result locatio migrate all the alloca_list to alloca_gen_list -inferred comptime - - - if (lval == LValNone) { - if (result_loc->id == ResultLocIdNone) - return value; - } - - assert(lval == LValPtr); - - // We needed a pointer to a value, but we got a value. So we create - // an instruction which just makes a pointer of it. - return ir_build_ref(irb, scope, value->source_node, value, false, false); +comptime expressions diff --git a/src/all_types.hpp b/src/all_types.hpp index d2e7a7f63..f13f16152 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -3102,8 +3102,8 @@ struct IrInstructionOptionalWrap { struct IrInstructionErrWrapPayload { IrInstruction base; - IrInstruction *value; - LLVMValueRef tmp_ptr; + IrInstruction *operand; + IrInstruction *result_loc; }; struct IrInstructionErrWrapCode { diff --git a/src/codegen.cpp b/src/codegen.cpp index e88cee418..69b234d16 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -5002,7 +5002,7 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa ZigType *err_set_type = wanted_type->data.error_union.err_set_type; if (!type_has_bits(err_set_type)) { - return ir_llvm_value(g, instruction->value); + return ir_llvm_value(g, instruction->operand); } LLVMValueRef ok_err_val = LLVMConstNull(get_llvm_type(g, g->err_tag_type)); @@ -5010,17 +5010,18 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa if (!type_has_bits(payload_type)) return ok_err_val; - assert(instruction->tmp_ptr); - LLVMValueRef payload_val = ir_llvm_value(g, instruction->value); + LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); - LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_err_index, ""); + LLVMValueRef payload_val = ir_llvm_value(g, instruction->operand); + + LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, ""); gen_store_untyped(g, ok_err_val, err_tag_ptr, 0, false); - LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_payload_index, ""); + LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_payload_index, ""); gen_assign_raw(g, payload_ptr, get_pointer_to_type(g, payload_type, false), payload_val); - return instruction->tmp_ptr; + return result_loc; } static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutable *executable, IrInstructionUnionTag *instruction) { @@ -6840,9 +6841,6 @@ static void do_code_gen(CodeGen *g) { slot = &ref_instruction->tmp_ptr; assert(instruction->value.type->id == ZigTypeIdPointer); slot_type = instruction->value.type->data.pointer.child_type; - } else if (instruction->id == IrInstructionIdErrWrapPayload) { - IrInstructionErrWrapPayload *err_wrap_payload_instruction = (IrInstructionErrWrapPayload *)instruction; - slot = &err_wrap_payload_instruction->tmp_ptr; } else if (instruction->id == IrInstructionIdErrWrapCode) { IrInstructionErrWrapCode *err_wrap_code_instruction = (IrInstructionErrWrapCode *)instruction; slot = &err_wrap_code_instruction->tmp_ptr; diff --git a/src/ir.cpp b/src/ir.cpp index 58f6b1445..10752cdc6 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -1773,11 +1773,17 @@ static IrInstruction *ir_build_optional_wrap(IrAnalyze *ira, IrInstruction *sour return &instruction->base; } -static IrInstruction *ir_build_err_wrap_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { - IrInstructionErrWrapPayload *instruction = ir_build_instruction(irb, scope, source_node); - instruction->value = value; +static IrInstruction *ir_build_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instruction, + ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc) +{ + IrInstructionErrWrapPayload *instruction = ir_build_instruction( + &ira->new_irb, source_instruction->scope, source_instruction->source_node); + instruction->base.value.type = result_type; + instruction->operand = operand; + instruction->result_loc = result_loc; - ir_ref_instruction(value, irb->current_basic_block); + ir_ref_instruction(operand, ira->new_irb.current_basic_block); + if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block); return &instruction->base; } @@ -11078,12 +11084,13 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so } static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr, - IrInstruction *value, ZigType *wanted_type) + IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc) { assert(wanted_type->id == ZigTypeIdErrorUnion); + ZigType *payload_type = wanted_type->data.error_union.payload_type; + ZigType *err_set_type = wanted_type->data.error_union.err_set_type; if (instr_is_comptime(value)) { - ZigType *payload_type = wanted_type->data.error_union.payload_type; IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type); if (type_is_invalid(casted_payload->value.type)) return ira->codegen->invalid_instruction; @@ -11093,7 +11100,7 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction return ira->codegen->invalid_instruction; ConstExprValue *err_set_val = create_const_vals(1); - err_set_val->type = wanted_type->data.error_union.err_set_type; + err_set_val->type = err_set_type; err_set_val->special = ConstValSpecialStatic; err_set_val->data.x_err_set = nullptr; @@ -11106,10 +11113,19 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction return &const_instruction->base; } - IrInstruction *result = ir_build_err_wrap_payload(&ira->new_irb, source_instr->scope, source_instr->source_node, value); - result->value.type = wanted_type; + IrInstruction *result_loc_inst; + if (handle_is_ptr(wanted_type)) { + if (result_loc == nullptr) result_loc = no_result_loc(); + result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr); + if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) { + return result_loc_inst; + } + } else { + result_loc_inst = nullptr; + } + + IrInstruction *result = ir_build_err_wrap_payload(ira, source_instr, wanted_type, value, result_loc_inst); result->value.data.rh_error_union = RuntimeHintErrorUnionNonError; - ir_add_alloca(ira, result, wanted_type); return result; } @@ -12057,12 +12073,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, source_node, false).id == ConstCastResultIdOk) { - return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); + return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, result_loc); } else if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdComptimeFloat) { if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) { - return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); + return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, result_loc); } else { return ira->codegen->invalid_instruction; } @@ -24447,7 +24463,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { case IrInstructionIdTestErr: case IrInstructionIdUnwrapErrCode: case IrInstructionIdErrWrapCode: - case IrInstructionIdErrWrapPayload: case IrInstructionIdFnProto: case IrInstructionIdTestComptime: case IrInstructionIdPtrCastSrc: @@ -24512,6 +24527,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { (IrInstructionUnwrapErrPayload *)instruction; return unwrap_err_payload_instruction->safety_check_on; } + case IrInstructionIdErrWrapPayload: + return reinterpret_cast(instruction)->result_loc != nullptr; } zig_unreachable(); } diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 6cad5c1de..7cff6f3d7 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -985,8 +985,9 @@ static void ir_print_err_wrap_code(IrPrint *irp, IrInstructionErrWrapCode *instr static void ir_print_err_wrap_payload(IrPrint *irp, IrInstructionErrWrapPayload *instruction) { fprintf(irp->f, "@errWrapPayload("); - ir_print_other_instruction(irp, instruction->value); - fprintf(irp->f, ")"); + ir_print_other_instruction(irp, instruction->operand); + fprintf(irp->f, ")result="); + ir_print_other_instruction(irp, instruction->result_loc); } static void ir_print_fn_proto(IrPrint *irp, IrInstructionFnProto *instruction) {