authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-12 22:13:18-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-12 22:13:18-04:00
logb552e68c143ead1b6bab662afd5b9fa8a7480f10
treee2be585174abec39147418d7b600e631afb523ed
parentcdf14baa45257a884fa20d8d992eb7be0d344005
signaturelock-open Commit is signed but in an unrecognized format.

fix result loc implicit casting optionals and error unions

```zig pub fn openHandle(handle: i32) File { return File{ .handle = handle }; } pub fn getStdErr() anyerror!File { return openHandle(1); } ```

1 files changed, 28 insertions(+), 25 deletions(-)

src/ir.cpp+28-25
...@@ -185,6 +185,8 @@ static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *sourc...@@ -185,6 +185,8 @@ static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *sourc
185 ZigType *ptr_type);185 ZigType *ptr_type);
186static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,186static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
187 ZigType *dest_type);187 ZigType *dest_type);
188static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr,
189 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value);
188static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr,190static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr,
189 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value);191 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value);
190static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr,192static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstruction *source_instr,
...@@ -14812,10 +14814,8 @@ static bool type_can_bit_cast(ZigType *t) {...@@ -14812,10 +14814,8 @@ static bool type_can_bit_cast(ZigType *t) {
14812 }14814 }
14813}14815}
1481414816
14815// give nullptr for value to resolve it at runtime
14816// returns a result location, or nullptr if the result location was already taken care of
14817// when calling this function, at the callsite must check for result type noreturn and propagate it up14817// when calling this function, at the callsite must check for result type noreturn and propagate it up
14818static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr,14818static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr,
14819 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value)14819 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value)
14820{14820{
14821 Error err;14821 Error err;
...@@ -14994,6 +14994,30 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s...@@ -14994,6 +14994,30 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s
14994 zig_unreachable();14994 zig_unreachable();
14995}14995}
1499614996
14997static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr,
14998 ResultLoc *result_loc_pass1, ZigType *value_type, IrInstruction *value)
14999{
15000 IrInstruction *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type,
15001 value);
15002 if (result_loc == nullptr || (instr_is_unreachable(result_loc) || type_is_invalid(result_loc->value.type)))
15003 return result_loc;
15004 ir_assert(result_loc->value.type->id == ZigTypeIdPointer, suspend_source_instr);
15005 ZigType *actual_elem_type = result_loc->value.type->data.pointer.child_type;
15006 if (actual_elem_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional) {
15007 return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true);
15008 } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion) {
15009 IrInstruction *unwrapped_err_ptr = ir_analyze_unwrap_error_payload(ira, suspend_source_instr,
15010 result_loc, false, true);
15011 ZigType *actual_payload_type = actual_elem_type->data.error_union.payload_type;
15012 if (actual_payload_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional) {
15013 return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, unwrapped_err_ptr, false, true);
15014 } else {
15015 return unwrapped_err_ptr;
15016 }
15017 }
15018 return result_loc;
15019}
15020
14997static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrInstructionImplicitCast *instruction) {15021static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrInstructionImplicitCast *instruction) {
14998 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child);15022 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child);
14999 if (type_is_invalid(dest_type))15023 if (type_is_invalid(dest_type))
...@@ -15010,25 +15034,7 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrIn...@@ -15010,25 +15034,7 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrIn
15010 ZigType *implicit_elem_type = ir_resolve_type(ira, instruction->ty->child);15034 ZigType *implicit_elem_type = ir_resolve_type(ira, instruction->ty->child);
15011 if (type_is_invalid(implicit_elem_type))15035 if (type_is_invalid(implicit_elem_type))
15012 return ira->codegen->invalid_instruction;15036 return ira->codegen->invalid_instruction;
15013 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,15037 return ir_resolve_result(ira, &instruction->base, instruction->result_loc, implicit_elem_type, nullptr);
15014 implicit_elem_type, nullptr);
15015 if (instr_is_unreachable(result_loc) || type_is_invalid(result_loc->value.type))
15016 return result_loc;
15017 ir_assert(result_loc->value.type->id == ZigTypeIdPointer, &instruction->base);
15018 ZigType *actual_elem_type = result_loc->value.type->data.pointer.child_type;
15019 if (actual_elem_type->id == ZigTypeIdOptional && implicit_elem_type->id != ZigTypeIdOptional) {
15020 return ir_analyze_unwrap_optional_payload(ira, &instruction->base, result_loc, false, true);
15021 } else if (actual_elem_type->id == ZigTypeIdErrorUnion && implicit_elem_type->id != ZigTypeIdErrorUnion) {
15022 IrInstruction *unwrapped_err_ptr = ir_analyze_unwrap_error_payload(ira, &instruction->base,
15023 result_loc, false, true);
15024 ZigType *actual_payload_type = actual_elem_type->data.error_union.payload_type;
15025 if (actual_payload_type->id == ZigTypeIdOptional && implicit_elem_type->id != ZigTypeIdOptional) {
15026 return ir_analyze_unwrap_optional_payload(ira, &instruction->base, unwrapped_err_ptr, false, true);
15027 } else {
15028 return unwrapped_err_ptr;
15029 }
15030 }
15031 return result_loc;
15032}15038}
1503315039
15034static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry,15040static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry,
...@@ -24617,9 +24623,6 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_...@@ -24617,9 +24623,6 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_
24617 continue;24623 continue;
24618 }24624 }
2461924625
24620 if (ira->codegen->verbose_ir) {
24621 fprintf(stderr, "analyze #%zu\n", old_instruction->debug_id);
24622 }
24623 IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction);24626 IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction);
24624 if (new_instruction != nullptr) {24627 if (new_instruction != nullptr) {
24625 ir_assert(new_instruction->value.type != nullptr || new_instruction->value.type != nullptr, old_instruction);24628 ir_assert(new_instruction->value.type != nullptr || new_instruction->value.type != nullptr, old_instruction);