authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-09-09 12:15:39-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-09-09 12:15:39-04:00
logf7721ac37cbb38c2f27d51f91eab776c5aca9767
tree24ea3ff81f3f1353591741163451312b5316f1b6
parent2482bdf22b77bdee718167da5390157cc792dced
signaturelock-open Commit is signed but in an unrecognized format.

implement spilling when returning error union async function call

closes #3190

2 files changed, 31 insertions(+), 2 deletions(-)

src/codegen.cpp+8-2
......@@ -4122,8 +4122,14 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
41224122 if (!type_has_bits(src_return_type))
41234123 return nullptr;
41244124
4125 if (result_loc != nullptr)
4126 return get_handle_value(g, result_loc, src_return_type, ptr_result_type);
4125 if (result_loc != nullptr) {
4126 if (instruction->result_loc->id == IrInstructionIdReturnPtr) {
4127 instruction->base.spill = nullptr;
4128 return g->cur_ret_ptr;
4129 } else {
4130 return get_handle_value(g, result_loc, src_return_type, ptr_result_type);
4131 }
4132 }
41274133
41284134 LLVMValueRef result_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, "");
41294135 return LLVMBuildLoad(g->builder, result_ptr, "");
test/stage1/behavior/async_fn.zig+23
......@@ -1178,3 +1178,26 @@ test "suspend in for loop" {
11781178 S.doTheTest();
11791179}
11801180
1181test "correctly spill when returning the error union result of another async fn" {
1182 const S = struct {
1183 var global_frame: anyframe = undefined;
1184
1185 fn doTheTest() void {
1186 expect((atest() catch unreachable) == 1234);
1187 }
1188
1189 fn atest() !i32 {
1190 return fallible1();
1191 }
1192
1193 fn fallible1() anyerror!i32 {
1194 suspend {
1195 global_frame = @frame();
1196 }
1197 return 1234;
1198 }
1199 };
1200 _ = async S.doTheTest();
1201 resume S.global_frame;
1202}
1203