diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2019-06-14 11:01:38 -0400 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2019-06-14 11:01:38 -0400 |
| commit | 2ba29a1907264d6466f187cd89552a63160d3922 (patch) | |
| tree | 05c4aa2c024529062a86c282ff32338c96230ae0 | |
| parent | fdaca1b5f3b7b72ed3a661bc52b6463838f366c4 (diff) | |
| download | zig-2ba29a1907264d6466f187cd89552a63160d3922.tar.gz zig-2ba29a1907264d6466f187cd89552a63160d3922.zip | |
fix peer result location with error code and payload
| -rw-r--r-- | src/all_types.hpp | 1 | ||||
| -rw-r--r-- | src/codegen.cpp | 1 | ||||
| -rw-r--r-- | src/ir.cpp | 67 | ||||
| -rw-r--r-- | test/stage1/behavior.zig | 14 |
4 files changed, 59 insertions, 24 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp index d81fec19e9..4609d246b6 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -3099,6 +3099,7 @@ struct IrInstructionTestErr { struct IrInstructionUnwrapErrCode { IrInstruction base; + bool initializing; IrInstruction *err_union_ptr; }; diff --git a/src/codegen.cpp b/src/codegen.cpp index a035c6b332..def2f6f8eb 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -4901,6 +4901,7 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executab if (!type_has_bits(payload_type)) { return err_union_ptr; } else { + // TODO assign undef to the payload LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type); return LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, ""); } diff --git a/src/ir.cpp b/src/ir.cpp index a292f9a79b..5dfd84ff15 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -193,6 +193,8 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr IrInstruction *base_ptr, bool safety_check_on, bool initializing); static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *base_ptr, bool safety_check_on, bool initializing); +static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr, + IrInstruction *base_ptr, bool initializing); static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { assert(get_src_ptr_type(const_val->type) != nullptr); @@ -15016,13 +15018,17 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s if (actual_elem_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional) { return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true); } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion) { - IrInstruction *unwrapped_err_ptr = ir_analyze_unwrap_error_payload(ira, suspend_source_instr, - result_loc, false, true); - ZigType *actual_payload_type = actual_elem_type->data.error_union.payload_type; - if (actual_payload_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional) { - return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, unwrapped_err_ptr, false, true); + if (value_type->id == ZigTypeIdErrorSet) { + return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, true); } else { - return unwrapped_err_ptr; + IrInstruction *unwrapped_err_ptr = ir_analyze_unwrap_error_payload(ira, suspend_source_instr, + result_loc, false, true); + ZigType *actual_payload_type = actual_elem_type->data.error_union.payload_type; + if (actual_payload_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional) { + return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, unwrapped_err_ptr, false, true); + } else { + return unwrapped_err_ptr; + } } } return result_loc; @@ -16437,6 +16443,9 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh peer_parent->base.source_instruction->source_node, expected_type, instructions, peer_parent->peer_count); + // the logic below assumes there are no instructions in the new current basic block yet + ir_assert(ira->new_irb.current_basic_block->instruction_list.length == 0, &phi_instruction->base); + // In case resolving the parent activates a suspend, do it now IrInstruction *parent_result_loc = ir_resolve_result(ira, &phi_instruction->base, peer_parent->parent, peer_parent->resolved_type, nullptr); @@ -16445,6 +16454,21 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh { return parent_result_loc; } + // If the above code generated any instructions in the current basic block, we need + // to move them to the peer parent predecessor. + ZigList<IrInstruction *> instrs_to_move = {}; + while (ira->new_irb.current_basic_block->instruction_list.length != 0) { + instrs_to_move.append(ira->new_irb.current_basic_block->instruction_list.pop()); + } + if (instrs_to_move.length != 0) { + IrBasicBlock *predecessor = peer_parent->base.source_instruction->child->owner_bb; + IrInstruction *branch_instruction = predecessor->instruction_list.pop(); + ir_assert(branch_instruction->value.type->id == ZigTypeIdUnreachable, &phi_instruction->base); + while (instrs_to_move.length != 0) { + predecessor->instruction_list.append(instrs_to_move.pop()); + } + predecessor->instruction_list.append(branch_instruction); + } } IrSuspendPosition suspend_pos; @@ -22213,10 +22237,9 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct } } -static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrInstructionUnwrapErrCode *instruction) { - IrInstruction *base_ptr = instruction->err_union_ptr->child; - if (type_is_invalid(base_ptr->value.type)) - return ira->codegen->invalid_instruction; +static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr, + IrInstruction *base_ptr, bool initializing) +{ ZigType *ptr_type = base_ptr->value.type; // 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 if (!ptr_val) return ira->codegen->invalid_instruction; if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { - ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.source_node); + ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); if (err_union_val == nullptr) return ira->codegen->invalid_instruction; if (err_union_val->special != ConstValSpecialRuntime) { ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; assert(err != nullptr); - IrInstruction *err_set_val = ir_const(ira, &instruction->base, - type_entry->data.error_union.err_set_type); + IrInstruction *err_set_val = ir_const(ira, source_instr, type_entry->data.error_union.err_set_type); err_set_val->value.data.x_err_set = err; err_set_val->value.parent.id = ConstParentIdErrUnionCode; err_set_val->value.parent.data.p_err_union_code.err_union_val = err_union_val; - return ir_get_ref(ira, &instruction->base, err_set_val, is_ptr_const, false); + return ir_get_ref(ira, source_instr, err_set_val, is_ptr_const, false); } } } IrInstruction *result = ir_build_unwrap_err_code(&ira->new_irb, - instruction->base.scope, instruction->base.source_node, base_ptr); + source_instr->scope, source_instr->source_node, base_ptr); result->value.type = get_pointer_to_type(ira->codegen, type_entry->data.error_union.err_set_type, is_ptr_const); return result; } +static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, + IrInstructionUnwrapErrCode *instruction) +{ + IrInstruction *base_ptr = instruction->err_union_ptr->child; + if (type_is_invalid(base_ptr->value.type)) + return ira->codegen->invalid_instruction; + return ir_analyze_unwrap_err_code(ira, &instruction->base, base_ptr, false); +} + static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *base_ptr, bool safety_check_on, bool initializing) { @@ -24783,7 +24814,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { case IrInstructionIdFrameAddress: case IrInstructionIdHandle: case IrInstructionIdTestErr: - case IrInstructionIdUnwrapErrCode: case IrInstructionIdFnProto: case IrInstructionIdTestComptime: case IrInstructionIdPtrCastSrc: @@ -24846,8 +24876,11 @@ bool ir_has_side_effects(IrInstruction *instruction) { { IrInstructionUnwrapErrPayload *unwrap_err_payload_instruction = (IrInstructionUnwrapErrPayload *)instruction; - return unwrap_err_payload_instruction->safety_check_on; + return unwrap_err_payload_instruction->safety_check_on || + unwrap_err_payload_instruction->initializing; } + case IrInstructionIdUnwrapErrCode: + return reinterpret_cast<IrInstructionUnwrapErrCode *>(instruction)->initializing; case IrInstructionIdErrWrapPayload: return reinterpret_cast<IrInstructionErrWrapPayload *>(instruction)->result_loc != nullptr; case IrInstructionIdErrWrapCode: diff --git a/test/stage1/behavior.zig b/test/stage1/behavior.zig index 56a3860199..56862e07a7 100644 --- a/test/stage1/behavior.zig +++ b/test/stage1/behavior.zig @@ -21,7 +21,7 @@ comptime { _ = @import("behavior/bugs/1486.zig"); _ = @import("behavior/bugs/1500.zig"); _ = @import("behavior/bugs/1607.zig"); - //_ = @import("behavior/bugs/1851.zig"); + _ = @import("behavior/bugs/1851.zig"); _ = @import("behavior/bugs/1914.zig"); _ = @import("behavior/bugs/2006.zig"); _ = @import("behavior/bugs/2114.zig"); @@ -41,16 +41,16 @@ comptime { _ = @import("behavior/byval_arg_var.zig"); //_ = @import("behavior/cancel.zig"); //_ = @import("behavior/cast.zig"); - //_ = @import("behavior/const_slice_child.zig"); + _ = @import("behavior/const_slice_child.zig"); //_ = @import("behavior/coroutine_await_struct.zig"); //_ = @import("behavior/coroutines.zig"); - //_ = @import("behavior/defer.zig"); + _ = @import("behavior/defer.zig"); //_ = @import("behavior/enum.zig"); //_ = @import("behavior/enum_with_members.zig"); //_ = @import("behavior/error.zig"); //_ = @import("behavior/eval.zig"); _ = @import("behavior/field_parent_ptr.zig"); - //_ = @import("behavior/fn.zig"); + _ = @import("behavior/fn.zig"); _ = @import("behavior/fn_in_struct_in_comptime.zig"); _ = @import("behavior/for.zig"); //_ = @import("behavior/generics.zig"); @@ -59,13 +59,13 @@ comptime { //_ = @import("behavior/import.zig"); _ = @import("behavior/incomplete_struct_param_tld.zig"); _ = @import("behavior/inttoptr.zig"); - //_ = @import("behavior/ir_block_deps.zig"); + _ = @import("behavior/ir_block_deps.zig"); //_ = @import("behavior/math.zig"); //_ = @import("behavior/merge_error_sets.zig"); //_ = @import("behavior/misc.zig"); _ = @import("behavior/namespace_depends_on_compile_var.zig"); _ = @import("behavior/new_stack_call.zig"); - //_ = @import("behavior/null.zig"); + _ = @import("behavior/null.zig"); //_ = @import("behavior/optional.zig"); //_ = @import("behavior/pointers.zig"); _ = @import("behavior/popcount.zig"); @@ -93,7 +93,7 @@ comptime { //_ = @import("behavior/union.zig"); _ = @import("behavior/var_args.zig"); _ = @import("behavior/vector.zig"); - //_ = @import("behavior/void.zig"); + _ = @import("behavior/void.zig"); //_ = @import("behavior/while.zig"); _ = @import("behavior/widening.zig"); } |
