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) {...@@ -330,6 +330,8 @@ static bool ir_should_inline(IrExecutable *exec, Scope *scope) {
330 while (scope != nullptr) {330 while (scope != nullptr) {
331 if (scope->id == ScopeIdCompTime)331 if (scope->id == ScopeIdCompTime)
332 return true;332 return true;
333 if (scope->id == ScopeIdTypeOf)
334 return false;
333 if (scope->id == ScopeIdFnDef)335 if (scope->id == ScopeIdFnDef)
334 break;336 break;
335 scope = scope->parent;337 scope = scope->parent;
...@@ -16075,11 +16077,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c...@@ -16075,11 +16077,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
16075 }16077 }
1607616078
16077 IrInstruction *result_loc;16079 IrInstruction *result_loc;
16078 if (call_instruction->is_async_call_builtin) {16080 if (handle_is_ptr(impl_fn_type_id->return_type)) {
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)) {
16083 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,16081 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
16084 impl_fn_type_id->return_type, nullptr, true, true, false);16082 impl_fn_type_id->return_type, nullptr, true, true, false);
16085 if (result_loc != nullptr) {16083 if (result_loc != nullptr) {
...@@ -16091,6 +16089,10 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c...@@ -16091,6 +16089,10 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
16091 result_loc = nullptr;16089 result_loc = nullptr;
16092 }16090 }
16093 }16091 }
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;
16094 } else {16096 } else {
16095 result_loc = nullptr;16097 result_loc = nullptr;
16096 }16098 }
...@@ -16231,11 +16233,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c...@@ -16231,11 +16233,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
16231 }16233 }
1623216234
16233 IrInstruction *result_loc;16235 IrInstruction *result_loc;
16234 if (call_instruction->is_async_call_builtin) {16236 if (handle_is_ptr(return_type)) {
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)) {
16239 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,16237 result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
16240 return_type, nullptr, true, true, false);16238 return_type, nullptr, true, true, false);
16241 if (result_loc != nullptr) {16239 if (result_loc != nullptr) {
...@@ -16247,6 +16245,10 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c...@@ -16247,6 +16245,10 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
16247 result_loc = nullptr;16245 result_loc = nullptr;
16248 }16246 }
16249 }16247 }
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;
16250 } else {16252 } else {
16251 result_loc = nullptr;16253 result_loc = nullptr;
16252 }16254 }
test/stage1/behavior/async_fn.zig+36
...@@ -1056,3 +1056,39 @@ test "using @typeOf on a generic function call" {...@@ -1056,3 +1056,39 @@ test "using @typeOf on a generic function call" {
1056 resume S.global_frame;1056 resume S.global_frame;
1057 expect(S.global_ok);1057 expect(S.global_ok);
1058}1058}
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}