| author | |
| committer | |
| log | f7721ac37cbb38c2f27d51f91eab776c5aca9767 |
| tree | 24ea3ff81f3f1353591741163451312b5316f1b6 |
| parent | 2482bdf22b77bdee718167da5390157cc792dced |
| signature |
closes #31902 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 |
| 4122 | 4122 | if (!type_has_bits(src_return_type)) |
| 4123 | 4123 | return nullptr; |
| 4124 | 4124 | |
| 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 | } | |
| 4127 | 4133 | |
| 4128 | 4134 | LLVMValueRef result_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, ""); |
| 4129 | 4135 | return LLVMBuildLoad(g->builder, result_ptr, ""); |
test/stage1/behavior/async_fn.zig+23| ... | ... | @@ -1178,3 +1178,26 @@ test "suspend in for loop" { |
| 1178 | 1178 | S.doTheTest(); |
| 1179 | 1179 | } |
| 1180 | 1180 | |
| 1181 | test "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 |