authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-09-02 14:35:41-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-09-02 14:35:41-04:00
logab4cba14c8aac7151b4c10094fea4211694da145
tree408ee5bea17a6bf3234208ae456eb2aff6ac359e
parentd291d3c8c00450e31b7cce15eae43db265361186
signaturelock-open Commit is signed but in an unrecognized format.

fix recursive call of await @asyncCall with struct return type


2 files changed, 48 insertions(+), 10 deletions(-)

src/ir.cpp+12-10
......@@ -330,6 +330,8 @@ static bool ir_should_inline(IrExecutable *exec, Scope *scope) {
330330 while (scope != nullptr) {
331331 if (scope->id == ScopeIdCompTime)
332332 return true;
333 if (scope->id == ScopeIdTypeOf)
334 return false;
333335 if (scope->id == ScopeIdFnDef)
334336 break;
335337 scope = scope->parent;
......@@ -16075,11 +16077,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
1607516077 }
1607616078
1607716079 IrInstruction *result_loc;
16078 if (call_instruction->is_async_call_builtin) {
16079 result_loc = get_async_call_result_loc(ira, call_instruction, impl_fn_type_id->return_type);
16080 if (result_loc != nullptr && type_is_invalid(result_loc->value.type))
16081 return ira->codegen->invalid_instruction;
16082 } else if (handle_is_ptr(impl_fn_type_id->return_type)) {
16080 if (handle_is_ptr(impl_fn_type_id->return_type)) {
1608316081 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
1608416082 impl_fn_type_id->return_type, nullptr, true, true, false);
1608516083 if (result_loc != nullptr) {
......@@ -16091,6 +16089,10 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
1609116089 result_loc = nullptr;
1609216090 }
1609316091 }
16092 } else if (call_instruction->is_async_call_builtin) {
16093 result_loc = get_async_call_result_loc(ira, call_instruction, impl_fn_type_id->return_type);
16094 if (result_loc != nullptr && type_is_invalid(result_loc->value.type))
16095 return ira->codegen->invalid_instruction;
1609416096 } else {
1609516097 result_loc = nullptr;
1609616098 }
......@@ -16231,11 +16233,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
1623116233 }
1623216234
1623316235 IrInstruction *result_loc;
16234 if (call_instruction->is_async_call_builtin) {
16235 result_loc = get_async_call_result_loc(ira, call_instruction, return_type);
16236 if (result_loc != nullptr && type_is_invalid(result_loc->value.type))
16237 return ira->codegen->invalid_instruction;
16238 } else if (handle_is_ptr(return_type)) {
16236 if (handle_is_ptr(return_type)) {
1623916237 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
1624016238 return_type, nullptr, true, true, false);
1624116239 if (result_loc != nullptr) {
......@@ -16247,6 +16245,10 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
1624716245 result_loc = nullptr;
1624816246 }
1624916247 }
16248 } else if (call_instruction->is_async_call_builtin) {
16249 result_loc = get_async_call_result_loc(ira, call_instruction, return_type);
16250 if (result_loc != nullptr && type_is_invalid(result_loc->value.type))
16251 return ira->codegen->invalid_instruction;
1625016252 } else {
1625116253 result_loc = nullptr;
1625216254 }
test/stage1/behavior/async_fn.zig+36
......@@ -1056,3 +1056,39 @@ test "using @typeOf on a generic function call" {
10561056 resume S.global_frame;
10571057 expect(S.global_ok);
10581058}
1059
1060test "recursive call of await @asyncCall with struct return type" {
1061 const S = struct {
1062 var global_frame: anyframe = undefined;
1063 var global_ok = false;
1064
1065 var buf: [100]u8 align(16) = undefined;
1066
1067 fn amain(x: var) Foo {
1068 if (x == 0) {
1069 global_ok = true;
1070 return Foo{ .x = 1, .y = 2, .z = 3 };
1071 }
1072 suspend {
1073 global_frame = @frame();
1074 }
1075 const F = @typeOf(async amain(x - 1));
1076 const frame = @intToPtr(*F, @ptrToInt(&buf));
1077 return await @asyncCall(frame, {}, amain, x - 1);
1078 }
1079
1080 const Foo = struct {
1081 x: u64,
1082 y: u64,
1083 z: u64,
1084 };
1085 };
1086 var res: S.Foo = undefined;
1087 var frame: @typeOf(async S.amain(u32(1))) = undefined;
1088 _ = @asyncCall(&frame, &res, S.amain, u32(1));
1089 resume S.global_frame;
1090 expect(S.global_ok);
1091 expect(res.x == 1);
1092 expect(res.y == 2);
1093 expect(res.z == 3);
1094}