authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-10 17:28:25-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-10 17:28:25-04:00
logb9c033ae1ac9c21a5729407b9a6ede88854654aa
tree421fbef2eaa5eecb2a83907779585b8a91c3ecd7
parent4f085b8d2c8ffb03dd15b789ad5867904faae13d
signaturelock-open Commit is signed but in an unrecognized format.

result location semantics for error union wrapping an error


4 files changed, 61 insertions(+), 39 deletions(-)

src/all_types.hpp+2-2
...@@ -3109,8 +3109,8 @@ struct IrInstructionErrWrapPayload {...@@ -3109,8 +3109,8 @@ struct IrInstructionErrWrapPayload {
3109struct IrInstructionErrWrapCode {3109struct IrInstructionErrWrapCode {
3110 IrInstruction base;3110 IrInstruction base;
31113111
3112 IrInstruction *value;3112 IrInstruction *operand;
3113 LLVMValueRef tmp_ptr;3113 IrInstruction *result_loc;
3114};3114};
31153115
3116struct IrInstructionFnProto {3116struct IrInstructionFnProto {
src/codegen.cpp+7-11
...@@ -4977,20 +4977,19 @@ static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutable *executable...@@ -4977,20 +4977,19 @@ static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutable *executable
49774977
4978 assert(wanted_type->id == ZigTypeIdErrorUnion);4978 assert(wanted_type->id == ZigTypeIdErrorUnion);
49794979
4980 ZigType *payload_type = wanted_type->data.error_union.payload_type;4980 LLVMValueRef err_val = ir_llvm_value(g, instruction->operand);
4981 ZigType *err_set_type = wanted_type->data.error_union.err_set_type;
49824981
4983 LLVMValueRef err_val = ir_llvm_value(g, instruction->value);4982 if (!handle_is_ptr(wanted_type))
4984
4985 if (!type_has_bits(payload_type) || !type_has_bits(err_set_type))
4986 return err_val;4983 return err_val;
49874984
4988 assert(instruction->tmp_ptr);4985 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
49894986
4990 LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_err_index, "");4987 LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, "");
4991 gen_store_untyped(g, err_val, err_tag_ptr, 0, false);4988 gen_store_untyped(g, err_val, err_tag_ptr, 0, false);
49924989
4993 return instruction->tmp_ptr;4990 // TODO store undef to the payload
4991
4992 return result_loc;
4994}4993}
49954994
4996static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executable, IrInstructionErrWrapPayload *instruction) {4995static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executable, IrInstructionErrWrapPayload *instruction) {
...@@ -6841,9 +6840,6 @@ static void do_code_gen(CodeGen *g) {...@@ -6841,9 +6840,6 @@ static void do_code_gen(CodeGen *g) {
6841 slot = &ref_instruction->tmp_ptr;6840 slot = &ref_instruction->tmp_ptr;
6842 assert(instruction->value.type->id == ZigTypeIdPointer);6841 assert(instruction->value.type->id == ZigTypeIdPointer);
6843 slot_type = instruction->value.type->data.pointer.child_type;6842 slot_type = instruction->value.type->data.pointer.child_type;
6844 } else if (instruction->id == IrInstructionIdErrWrapCode) {
6845 IrInstructionErrWrapCode *err_wrap_code_instruction = (IrInstructionErrWrapCode *)instruction;
6846 slot = &err_wrap_code_instruction->tmp_ptr;
6847 } else if (instruction->id == IrInstructionIdCmpxchgGen) {6843 } else if (instruction->id == IrInstructionIdCmpxchgGen) {
6848 IrInstructionCmpxchgGen *cmpxchg_instruction = (IrInstructionCmpxchgGen *)instruction;6844 IrInstructionCmpxchgGen *cmpxchg_instruction = (IrInstructionCmpxchgGen *)instruction;
6849 slot = &cmpxchg_instruction->tmp_ptr;6845 slot = &cmpxchg_instruction->tmp_ptr;
src/ir.cpp+49-24
...@@ -1788,11 +1788,17 @@ static IrInstruction *ir_build_err_wrap_payload(IrAnalyze *ira, IrInstruction *s...@@ -1788,11 +1788,17 @@ static IrInstruction *ir_build_err_wrap_payload(IrAnalyze *ira, IrInstruction *s
1788 return &instruction->base;1788 return &instruction->base;
1789}1789}
17901790
1791static IrInstruction *ir_build_err_wrap_code(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {1791static IrInstruction *ir_build_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instruction,
1792 IrInstructionErrWrapCode *instruction = ir_build_instruction<IrInstructionErrWrapCode>(irb, scope, source_node);1792 ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc)
1793 instruction->value = value;1793{
1794 IrInstructionErrWrapCode *instruction = ir_build_instruction<IrInstructionErrWrapCode>(
1795 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
1796 instruction->base.value.type = result_type;
1797 instruction->operand = operand;
1798 instruction->result_loc = result_loc;
17941799
1795 ir_ref_instruction(value, irb->current_basic_block);1800 ir_ref_instruction(operand, ira->new_irb.current_basic_block);
1801 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
17961802
1797 return &instruction->base;1803 return &instruction->base;
1798}1804}
...@@ -11172,7 +11178,9 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou...@@ -11172,7 +11178,9 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou
11172 return result;11178 return result;
11173}11179}
1117411180
11175static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *wanted_type) {11181static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
11182 ZigType *wanted_type, ResultLoc *result_loc)
11183{
11176 assert(wanted_type->id == ZigTypeIdErrorUnion);11184 assert(wanted_type->id == ZigTypeIdErrorUnion);
1117711185
11178 IrInstruction *casted_value = ir_implicit_cast(ira, value, wanted_type->data.error_union.err_set_type);11186 IrInstruction *casted_value = ir_implicit_cast(ira, value, wanted_type->data.error_union.err_set_type);
...@@ -11196,10 +11204,20 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so...@@ -11196,10 +11204,20 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so
11196 return &const_instruction->base;11204 return &const_instruction->base;
11197 }11205 }
1119811206
11199 IrInstruction *result = ir_build_err_wrap_code(&ira->new_irb, source_instr->scope, source_instr->source_node, value);11207 IrInstruction *result_loc_inst;
11200 result->value.type = wanted_type;11208 if (handle_is_ptr(wanted_type)) {
11209 if (result_loc == nullptr) result_loc = no_result_loc();
11210 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr);
11211 if (type_is_invalid(result_loc_inst->value.type) || instr_is_unreachable(result_loc_inst)) {
11212 return result_loc_inst;
11213 }
11214 } else {
11215 result_loc_inst = nullptr;
11216 }
11217
11218
11219 IrInstruction *result = ir_build_err_wrap_code(ira, source_instr, wanted_type, value, result_loc_inst);
11201 result->value.data.rh_error_union = RuntimeHintErrorUnionError;11220 result->value.data.rh_error_union = RuntimeHintErrorUnionError;
11202 ir_add_alloca(ira, result, wanted_type);
11203 return result;11221 return result;
11204}11222}
1120511223
...@@ -12293,7 +12311,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -12293,7 +12311,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
12293 if (wanted_type->id == ZigTypeIdErrorUnion &&12311 if (wanted_type->id == ZigTypeIdErrorUnion &&
12294 actual_type->id == ZigTypeIdErrorSet)12312 actual_type->id == ZigTypeIdErrorSet)
12295 {12313 {
12296 return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type);12314 return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type, result_loc);
12297 }12315 }
1229812316
12299 // cast from typed number to integer or float literal.12317 // cast from typed number to integer or float literal.
...@@ -15615,12 +15633,16 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c...@@ -15615,12 +15633,16 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
15615 }15633 }
1561615634
15617 FnTypeId *impl_fn_type_id = &impl_fn->type_entry->data.fn.fn_type_id;15635 FnTypeId *impl_fn_type_id = &impl_fn->type_entry->data.fn.fn_type_id;
15618 IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,15636 IrInstruction *result_loc;
15619 impl_fn_type_id->return_type, nullptr);15637 if (handle_is_ptr(impl_fn_type_id->return_type)) {
15620 if (result_loc != nullptr &&15638 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
15621 (type_is_invalid(result_loc->value.type) || result_loc->value.type->id == ZigTypeIdUnreachable))15639 impl_fn_type_id->return_type, nullptr);
15622 {15640 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
15623 return result_loc;15641 return result_loc;
15642 }
15643 call_instruction->result_loc->written = true;
15644 } else {
15645 result_loc = nullptr;
15624 }15646 }
1562515647
15626 if (fn_type_can_fail(impl_fn_type_id)) {15648 if (fn_type_can_fail(impl_fn_type_id)) {
...@@ -15634,7 +15656,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c...@@ -15634,7 +15656,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
15634 return ir_finish_anal(ira, result);15656 return ir_finish_anal(ira, result);
15635 }15657 }
1563615658
15637 call_instruction->result_loc->written = handle_is_ptr(impl_fn_type_id->return_type);
15638 assert(async_allocator_inst == nullptr);15659 assert(async_allocator_inst == nullptr);
15639 IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base,15660 IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base,
15640 impl_fn, nullptr, impl_param_count, casted_args, fn_inline,15661 impl_fn, nullptr, impl_param_count, casted_args, fn_inline,
...@@ -15733,15 +15754,18 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c...@@ -15733,15 +15754,18 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
15733 return ira->codegen->invalid_instruction;15754 return ira->codegen->invalid_instruction;
15734 }15755 }
1573515756
15736 IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,15757 IrInstruction *result_loc;
15737 return_type, nullptr);15758 if (handle_is_ptr(return_type)) {
15738 if (result_loc != nullptr &&15759 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
15739 (type_is_invalid(result_loc->value.type) || result_loc->value.type->id == ZigTypeIdUnreachable))15760 return_type, nullptr);
15740 {15761 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
15741 return result_loc;15762 return result_loc;
15763 }
15764 call_instruction->result_loc->written = true;
15765 } else {
15766 result_loc = nullptr;
15742 }15767 }
1574315768
15744 call_instruction->result_loc->written = handle_is_ptr(return_type);
15745 IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref,15769 IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref,
15746 call_param_count, casted_args, fn_inline, false, nullptr, casted_new_stack,15770 call_param_count, casted_args, fn_inline, false, nullptr, casted_new_stack,
15747 result_loc, return_type);15771 result_loc, return_type);
...@@ -24462,7 +24486,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -24462,7 +24486,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
24462 case IrInstructionIdHandle:24486 case IrInstructionIdHandle:
24463 case IrInstructionIdTestErr:24487 case IrInstructionIdTestErr:
24464 case IrInstructionIdUnwrapErrCode:24488 case IrInstructionIdUnwrapErrCode:
24465 case IrInstructionIdErrWrapCode:
24466 case IrInstructionIdFnProto:24489 case IrInstructionIdFnProto:
24467 case IrInstructionIdTestComptime:24490 case IrInstructionIdTestComptime:
24468 case IrInstructionIdPtrCastSrc:24491 case IrInstructionIdPtrCastSrc:
...@@ -24529,6 +24552,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -24529,6 +24552,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
24529 }24552 }
24530 case IrInstructionIdErrWrapPayload:24553 case IrInstructionIdErrWrapPayload:
24531 return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr;24554 return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr;
24555 case IrInstructionIdErrWrapCode:
24556 return reinterpret_cast<IrInstructionErrWrapCode *>(instruction)->result_loc != nullptr;
24532 }24557 }
24533 zig_unreachable();24558 zig_unreachable();
24534}24559}
src/ir_print.cpp+3-2
...@@ -979,8 +979,9 @@ static void ir_print_optional_wrap(IrPrint *irp, IrInstructionOptionalWrap *inst...@@ -979,8 +979,9 @@ static void ir_print_optional_wrap(IrPrint *irp, IrInstructionOptionalWrap *inst
979979
980static void ir_print_err_wrap_code(IrPrint *irp, IrInstructionErrWrapCode *instruction) {980static void ir_print_err_wrap_code(IrPrint *irp, IrInstructionErrWrapCode *instruction) {
981 fprintf(irp->f, "@errWrapCode(");981 fprintf(irp->f, "@errWrapCode(");
982 ir_print_other_instruction(irp, instruction->value);982 ir_print_other_instruction(irp, instruction->operand);
983 fprintf(irp->f, ")");983 fprintf(irp->f, ")result=");
984 ir_print_other_instruction(irp, instruction->result_loc);
984}985}
985986
986static void ir_print_err_wrap_payload(IrPrint *irp, IrInstructionErrWrapPayload *instruction) {987static void ir_print_err_wrap_payload(IrPrint *irp, IrInstructionErrWrapPayload *instruction) {