authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-10 16:55:07-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-10 16:55:07-04:00
log4f085b8d2c8ffb03dd15b789ad5867904faae13d
tree85d72c0cba9b4a6d6803e3e5dd83210a1699033e
parenteaa9d8bdac7f64e38a39607e5d5574f88f8fe875
signature Commit is signed but in an unrecognized format.

result location semantics for error union wrapping a payload


5 files changed, 43 insertions(+), 39 deletions(-)

BRANCH_TODO+1-13
...@@ -6,17 +6,5 @@ look at all the ir_gen_node ir_gen_node_extra calls and make sure result locatio...@@ -6,17 +6,5 @@ look at all the ir_gen_node ir_gen_node_extra calls and make sure result locatio
66
7migrate all the alloca_list to alloca_gen_list7migrate all the alloca_list to alloca_gen_list
88
9inferred comptime9comptime expressions
10
11
12 if (lval == LValNone) {
13 if (result_loc->id == ResultLocIdNone)
14 return value;
15 }
16
17 assert(lval == LValPtr);
18
19 // We needed a pointer to a value, but we got a value. So we create
20 // an instruction which just makes a pointer of it.
21 return ir_build_ref(irb, scope, value->source_node, value, false, false);
2210
src/all_types.hpp+2-2
...@@ -3102,8 +3102,8 @@ struct IrInstructionOptionalWrap {...@@ -3102,8 +3102,8 @@ struct IrInstructionOptionalWrap {
3102struct IrInstructionErrWrapPayload {3102struct IrInstructionErrWrapPayload {
3103 IrInstruction base;3103 IrInstruction base;
31043104
3105 IrInstruction *value;3105 IrInstruction *operand;
3106 LLVMValueRef tmp_ptr;3106 IrInstruction *result_loc;
3107};3107};
31083108
3109struct IrInstructionErrWrapCode {3109struct IrInstructionErrWrapCode {
src/codegen.cpp+7-9
...@@ -5002,7 +5002,7 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa...@@ -5002,7 +5002,7 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa
5002 ZigType *err_set_type = wanted_type->data.error_union.err_set_type;5002 ZigType *err_set_type = wanted_type->data.error_union.err_set_type;
50035003
5004 if (!type_has_bits(err_set_type)) {5004 if (!type_has_bits(err_set_type)) {
5005 return ir_llvm_value(g, instruction->value);5005 return ir_llvm_value(g, instruction->operand);
5006 }5006 }
50075007
5008 LLVMValueRef ok_err_val = LLVMConstNull(get_llvm_type(g, g->err_tag_type));5008 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...@@ -5010,17 +5010,18 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executa
5010 if (!type_has_bits(payload_type))5010 if (!type_has_bits(payload_type))
5011 return ok_err_val;5011 return ok_err_val;
50125012
5013 assert(instruction->tmp_ptr);
50145013
5015 LLVMValueRef payload_val = ir_llvm_value(g, instruction->value);5014 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
50165015
5017 LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_err_index, "");5016 LLVMValueRef payload_val = ir_llvm_value(g, instruction->operand);
5017
5018 LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, "");
5018 gen_store_untyped(g, ok_err_val, err_tag_ptr, 0, false);5019 gen_store_untyped(g, ok_err_val, err_tag_ptr, 0, false);
50195020
5020 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_payload_index, "");5021 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_payload_index, "");
5021 gen_assign_raw(g, payload_ptr, get_pointer_to_type(g, payload_type, false), payload_val);5022 gen_assign_raw(g, payload_ptr, get_pointer_to_type(g, payload_type, false), payload_val);
50225023
5023 return instruction->tmp_ptr;5024 return result_loc;
5024}5025}
50255026
5026static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutable *executable, IrInstructionUnionTag *instruction) {5027static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutable *executable, IrInstructionUnionTag *instruction) {
...@@ -6840,9 +6841,6 @@ static void do_code_gen(CodeGen *g) {...@@ -6840,9 +6841,6 @@ static void do_code_gen(CodeGen *g) {
6840 slot = &ref_instruction->tmp_ptr;6841 slot = &ref_instruction->tmp_ptr;
6841 assert(instruction->value.type->id == ZigTypeIdPointer);6842 assert(instruction->value.type->id == ZigTypeIdPointer);
6842 slot_type = instruction->value.type->data.pointer.child_type;6843 slot_type = instruction->value.type->data.pointer.child_type;
6843 } else if (instruction->id == IrInstructionIdErrWrapPayload) {
6844 IrInstructionErrWrapPayload *err_wrap_payload_instruction = (IrInstructionErrWrapPayload *)instruction;
6845 slot = &err_wrap_payload_instruction->tmp_ptr;
6846 } else if (instruction->id == IrInstructionIdErrWrapCode) {6844 } else if (instruction->id == IrInstructionIdErrWrapCode) {
6847 IrInstructionErrWrapCode *err_wrap_code_instruction = (IrInstructionErrWrapCode *)instruction;6845 IrInstructionErrWrapCode *err_wrap_code_instruction = (IrInstructionErrWrapCode *)instruction;
6848 slot = &err_wrap_code_instruction->tmp_ptr;6846 slot = &err_wrap_code_instruction->tmp_ptr;
src/ir.cpp+30-13
...@@ -1773,11 +1773,17 @@ static IrInstruction *ir_build_optional_wrap(IrAnalyze *ira, IrInstruction *sour...@@ -1773,11 +1773,17 @@ static IrInstruction *ir_build_optional_wrap(IrAnalyze *ira, IrInstruction *sour
1773 return &instruction->base;1773 return &instruction->base;
1774}1774}
17751775
1776static IrInstruction *ir_build_err_wrap_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {1776static IrInstruction *ir_build_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instruction,
1777 IrInstructionErrWrapPayload *instruction = ir_build_instruction<IrInstructionErrWrapPayload>(irb, scope, source_node);1777 ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc)
1778 instruction->value = value;1778{
1779 IrInstructionErrWrapPayload *instruction = ir_build_instruction<IrInstructionErrWrapPayload>(
1780 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
1781 instruction->base.value.type = result_type;
1782 instruction->operand = operand;
1783 instruction->result_loc = result_loc;
17791784
1780 ir_ref_instruction(value, irb->current_basic_block);1785 ir_ref_instruction(operand, ira->new_irb.current_basic_block);
1786 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
17811787
1782 return &instruction->base;1788 return &instruction->base;
1783}1789}
...@@ -11078,12 +11084,13 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so...@@ -11078,12 +11084,13 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so
11078}11084}
1107911085
11080static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr,11086static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr,
11081 IrInstruction *value, ZigType *wanted_type)11087 IrInstruction *value, ZigType *wanted_type, ResultLoc *result_loc)
11082{11088{
11083 assert(wanted_type->id == ZigTypeIdErrorUnion);11089 assert(wanted_type->id == ZigTypeIdErrorUnion);
1108411090
11091 ZigType *payload_type = wanted_type->data.error_union.payload_type;
11092 ZigType *err_set_type = wanted_type->data.error_union.err_set_type;
11085 if (instr_is_comptime(value)) {11093 if (instr_is_comptime(value)) {
11086 ZigType *payload_type = wanted_type->data.error_union.payload_type;
11087 IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type);11094 IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type);
11088 if (type_is_invalid(casted_payload->value.type))11095 if (type_is_invalid(casted_payload->value.type))
11089 return ira->codegen->invalid_instruction;11096 return ira->codegen->invalid_instruction;
...@@ -11093,7 +11100,7 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction...@@ -11093,7 +11100,7 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction
11093 return ira->codegen->invalid_instruction;11100 return ira->codegen->invalid_instruction;
1109411101
11095 ConstExprValue *err_set_val = create_const_vals(1);11102 ConstExprValue *err_set_val = create_const_vals(1);
11096 err_set_val->type = wanted_type->data.error_union.err_set_type;11103 err_set_val->type = err_set_type;
11097 err_set_val->special = ConstValSpecialStatic;11104 err_set_val->special = ConstValSpecialStatic;
11098 err_set_val->data.x_err_set = nullptr;11105 err_set_val->data.x_err_set = nullptr;
1109911106
...@@ -11106,10 +11113,19 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction...@@ -11106,10 +11113,19 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction
11106 return &const_instruction->base;11113 return &const_instruction->base;
11107 }11114 }
1110811115
11109 IrInstruction *result = ir_build_err_wrap_payload(&ira->new_irb, source_instr->scope, source_instr->source_node, value);11116 IrInstruction *result_loc_inst;
11110 result->value.type = wanted_type;11117 if (handle_is_ptr(wanted_type)) {
11118 if (result_loc == nullptr) result_loc = no_result_loc();
11119 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr);
11120 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
11121 return result_loc_inst;
11122 }
11123 } else {
11124 result_loc_inst = nullptr;
11125 }
11126
11127 IrInstruction *result = ir_build_err_wrap_payload(ira, source_instr, wanted_type, value, result_loc_inst);
11111 result->value.data.rh_error_union = RuntimeHintErrorUnionNonError;11128 result->value.data.rh_error_union = RuntimeHintErrorUnionNonError;
11112 ir_add_alloca(ira, result, wanted_type);
11113 return result;11129 return result;
11114}11130}
1111511131
...@@ -12057,12 +12073,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -12057,12 +12073,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
12057 if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type,12073 if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type,
12058 source_node, false).id == ConstCastResultIdOk)12074 source_node, false).id == ConstCastResultIdOk)
12059 {12075 {
12060 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);12076 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, result_loc);
12061 } else if (actual_type->id == ZigTypeIdComptimeInt ||12077 } else if (actual_type->id == ZigTypeIdComptimeInt ||
12062 actual_type->id == ZigTypeIdComptimeFloat)12078 actual_type->id == ZigTypeIdComptimeFloat)
12063 {12079 {
12064 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) {12080 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) {
12065 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);12081 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, result_loc);
12066 } else {12082 } else {
12067 return ira->codegen->invalid_instruction;12083 return ira->codegen->invalid_instruction;
12068 }12084 }
...@@ -24447,7 +24463,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -24447,7 +24463,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
24447 case IrInstructionIdTestErr:24463 case IrInstructionIdTestErr:
24448 case IrInstructionIdUnwrapErrCode:24464 case IrInstructionIdUnwrapErrCode:
24449 case IrInstructionIdErrWrapCode:24465 case IrInstructionIdErrWrapCode:
24450 case IrInstructionIdErrWrapPayload:
24451 case IrInstructionIdFnProto:24466 case IrInstructionIdFnProto:
24452 case IrInstructionIdTestComptime:24467 case IrInstructionIdTestComptime:
24453 case IrInstructionIdPtrCastSrc:24468 case IrInstructionIdPtrCastSrc:
...@@ -24512,6 +24527,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -24512,6 +24527,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
24512 (IrInstructionUnwrapErrPayload *)instruction;24527 (IrInstructionUnwrapErrPayload *)instruction;
24513 return unwrap_err_payload_instruction->safety_check_on;24528 return unwrap_err_payload_instruction->safety_check_on;
24514 }24529 }
24530 case IrInstructionIdErrWrapPayload:
24531 return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr;
24515 }24532 }
24516 zig_unreachable();24533 zig_unreachable();
24517}24534}
src/ir_print.cpp+3-2
...@@ -985,8 +985,9 @@ static void ir_print_err_wrap_code(IrPrint *irp, IrInstructionErrWrapCode *instr...@@ -985,8 +985,9 @@ static void ir_print_err_wrap_code(IrPrint *irp, IrInstructionErrWrapCode *instr
985985
986static void ir_print_err_wrap_payload(IrPrint *irp, IrInstructionErrWrapPayload *instruction) {986static void ir_print_err_wrap_payload(IrPrint *irp, IrInstructionErrWrapPayload *instruction) {
987 fprintf(irp->f, "@errWrapPayload(");987 fprintf(irp->f, "@errWrapPayload(");
988 ir_print_other_instruction(irp, instruction->value);988 ir_print_other_instruction(irp, instruction->operand);
989 fprintf(irp->f, ")");989 fprintf(irp->f, ")result=");
990 ir_print_other_instruction(irp, instruction->result_loc);
990}991}
991992
992static void ir_print_fn_proto(IrPrint *irp, IrInstructionFnProto *instruction) {993static void ir_print_fn_proto(IrPrint *irp, IrInstructionFnProto *instruction) {