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 {
31093109struct IrInstructionErrWrapCode {
31103110 IrInstruction base;
31113111
3112 IrInstruction *value;
3113 LLVMValueRef tmp_ptr;
3112 IrInstruction *operand;
3113 IrInstruction *result_loc;
31143114};
31153115
31163116struct IrInstructionFnProto {
src/codegen.cpp+7-11
......@@ -4977,20 +4977,19 @@ static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutable *executable
49774977
49784978 assert(wanted_type->id == ZigTypeIdErrorUnion);
49794979
4980 ZigType *payload_type = wanted_type->data.error_union.payload_type;
4981 ZigType *err_set_type = wanted_type->data.error_union.err_set_type;
4980 LLVMValueRef err_val = ir_llvm_value(g, instruction->operand);
49824981
4983 LLVMValueRef err_val = ir_llvm_value(g, instruction->value);
4984
4985 if (!type_has_bits(payload_type) || !type_has_bits(err_set_type))
4982 if (!handle_is_ptr(wanted_type))
49864983 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, "");
49914988 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;
49944993}
49954994
49964995static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executable, IrInstructionErrWrapPayload *instruction) {
......@@ -6841,9 +6840,6 @@ static void do_code_gen(CodeGen *g) {
68416840 slot = &ref_instruction->tmp_ptr;
68426841 assert(instruction->value.type->id == ZigTypeIdPointer);
68436842 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;
68476843 } else if (instruction->id == IrInstructionIdCmpxchgGen) {
68486844 IrInstructionCmpxchgGen *cmpxchg_instruction = (IrInstructionCmpxchgGen *)instruction;
68496845 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
17881788 return &instruction->base;
17891789}
17901790
1791static IrInstruction *ir_build_err_wrap_code(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
1792 IrInstructionErrWrapCode *instruction = ir_build_instruction<IrInstructionErrWrapCode>(irb, scope, source_node);
1793 instruction->value = value;
1791static IrInstruction *ir_build_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instruction,
1792 ZigType *result_type, IrInstruction *operand, IrInstruction *result_loc)
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
17971803 return &instruction->base;
17981804}
......@@ -11172,7 +11178,9 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou
1117211178 return result;
1117311179}
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{
1117611184 assert(wanted_type->id == ZigTypeIdErrorUnion);
1117711185
1117811186 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
1119611204 return &const_instruction->base;
1119711205 }
1119811206
11199 IrInstruction *result = ir_build_err_wrap_code(&ira->new_irb, source_instr->scope, source_instr->source_node, value);
11200 result->value.type = wanted_type;
11207 IrInstruction *result_loc_inst;
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);
1120111220 result->value.data.rh_error_union = RuntimeHintErrorUnionError;
11202 ir_add_alloca(ira, result, wanted_type);
1120311221 return result;
1120411222}
1120511223
......@@ -12293,7 +12311,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1229312311 if (wanted_type->id == ZigTypeIdErrorUnion &&
1229412312 actual_type->id == ZigTypeIdErrorSet)
1229512313 {
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);
1229712315 }
1229812316
1229912317 // cast from typed number to integer or float literal.
......@@ -15615,12 +15633,16 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
1561515633 }
1561615634
1561715635 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,
15619 impl_fn_type_id->return_type, nullptr);
15620 if (result_loc != nullptr &&
15621 (type_is_invalid(result_loc->value.type) || result_loc->value.type->id == ZigTypeIdUnreachable))
15622 {
15623 return result_loc;
15636 IrInstruction *result_loc;
15637 if (handle_is_ptr(impl_fn_type_id->return_type)) {
15638 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
15639 impl_fn_type_id->return_type, nullptr);
15640 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
15641 return result_loc;
15642 }
15643 call_instruction->result_loc->written = true;
15644 } else {
15645 result_loc = nullptr;
1562415646 }
1562515647
1562615648 if (fn_type_can_fail(impl_fn_type_id)) {
......@@ -15634,7 +15656,6 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
1563415656 return ir_finish_anal(ira, result);
1563515657 }
1563615658
15637 call_instruction->result_loc->written = handle_is_ptr(impl_fn_type_id->return_type);
1563815659 assert(async_allocator_inst == nullptr);
1563915660 IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base,
1564015661 impl_fn, nullptr, impl_param_count, casted_args, fn_inline,
......@@ -15733,15 +15754,18 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
1573315754 return ira->codegen->invalid_instruction;
1573415755 }
1573515756
15736 IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
15737 return_type, nullptr);
15738 if (result_loc != nullptr &&
15739 (type_is_invalid(result_loc->value.type) || result_loc->value.type->id == ZigTypeIdUnreachable))
15740 {
15741 return result_loc;
15757 IrInstruction *result_loc;
15758 if (handle_is_ptr(return_type)) {
15759 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
15760 return_type, nullptr);
15761 if (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)) {
15762 return result_loc;
15763 }
15764 call_instruction->result_loc->written = true;
15765 } else {
15766 result_loc = nullptr;
1574215767 }
1574315768
15744 call_instruction->result_loc->written = handle_is_ptr(return_type);
1574515769 IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref,
1574615770 call_param_count, casted_args, fn_inline, false, nullptr, casted_new_stack,
1574715771 result_loc, return_type);
......@@ -24462,7 +24486,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2446224486 case IrInstructionIdHandle:
2446324487 case IrInstructionIdTestErr:
2446424488 case IrInstructionIdUnwrapErrCode:
24465 case IrInstructionIdErrWrapCode:
2446624489 case IrInstructionIdFnProto:
2446724490 case IrInstructionIdTestComptime:
2446824491 case IrInstructionIdPtrCastSrc:
......@@ -24529,6 +24552,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2452924552 }
2453024553 case IrInstructionIdErrWrapPayload:
2453124554 return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr;
24555 case IrInstructionIdErrWrapCode:
24556 return reinterpret_cast<IrInstructionErrWrapCode *>(instruction)->result_loc != nullptr;
2453224557 }
2453324558 zig_unreachable();
2453424559}
src/ir_print.cpp+3-2
......@@ -979,8 +979,9 @@ static void ir_print_optional_wrap(IrPrint *irp, IrInstructionOptionalWrap *inst
979979
980980static void ir_print_err_wrap_code(IrPrint *irp, IrInstructionErrWrapCode *instruction) {
981981 fprintf(irp->f, "@errWrapCode(");
982 ir_print_other_instruction(irp, instruction->value);
983 fprintf(irp->f, ")");
982 ir_print_other_instruction(irp, instruction->operand);
983 fprintf(irp->f, ")result=");
984 ir_print_other_instruction(irp, instruction->result_loc);
984985}
985986
986987static void ir_print_err_wrap_payload(IrPrint *irp, IrInstructionErrWrapPayload *instruction) {