authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-10 17:23:45-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-10 17:23:45-04:00
log77d098e92d1f7d69e4067db811333982ad98190a
treeb15fa0f27e136f55b108105e051676c767d23247
parent22428a75462e01877181501801dce4c090a87e9c
signature Commit is signed but in an unrecognized format.

fix returning a const error from async function


2 files changed, 39 insertions(+), 7 deletions(-)

src/codegen.cpp+11-7
...@@ -2280,13 +2280,16 @@ static LLVMValueRef ir_render_return_begin(CodeGen *g, IrExecutable *executable,...@@ -2280,13 +2280,16 @@ static LLVMValueRef ir_render_return_begin(CodeGen *g, IrExecutable *executable,
2280 return operand_has_bits ? ir_llvm_value(g, instruction->operand) : nullptr;2280 return operand_has_bits ? ir_llvm_value(g, instruction->operand) : nullptr;
2281 }2281 }
22822282
2283 ZigType *ret_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type;
2284 bool ret_type_has_bits = type_has_bits(ret_type);
2285 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;2283 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
22862284 if (operand_has_bits && instruction->operand != nullptr) {
2287 if (ret_type_has_bits && !handle_is_ptr(ret_type)) {2285 ZigType *ret_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type;
2288 // It's a scalar, so it didn't get written to the result ptr. Do that before the atomic rmw.2286 bool need_store = instruction->operand->value.special != ConstValSpecialRuntime || !handle_is_ptr(ret_type);
2289 LLVMBuildStore(g->builder, ir_llvm_value(g, instruction->operand), g->cur_ret_ptr);2287 if (need_store) {
2288 // It didn't get written to the result ptr. We do that now so that we do not have to spill
2289 // the return operand.
2290 ZigType *ret_ptr_type = get_pointer_to_type(g, ret_type, true);
2291 gen_assign_raw(g, g->cur_ret_ptr, ret_ptr_type, ir_llvm_value(g, instruction->operand));
2292 }
2290 }2293 }
22912294
2292 // Prepare to be suspended. We might end up not having to suspend though.2295 // Prepare to be suspended. We might end up not having to suspend though.
...@@ -2387,6 +2390,8 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns...@@ -2387,6 +2390,8 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns
2387 LLVMSetTailCall(call_inst, true);2390 LLVMSetTailCall(call_inst, true);
2388 LLVMBuildRetVoid(g->builder);2391 LLVMBuildRetVoid(g->builder);
23892392
2393 g->cur_is_after_return = false;
2394
2390 return nullptr;2395 return nullptr;
2391 }2396 }
2392 if (want_first_arg_sret(g, &g->cur_fn->type_entry->data.fn.fn_type_id)) {2397 if (want_first_arg_sret(g, &g->cur_fn->type_entry->data.fn.fn_type_id)) {
...@@ -7117,7 +7122,6 @@ static void do_code_gen(CodeGen *g) {...@@ -7117,7 +7122,6 @@ static void do_code_gen(CodeGen *g) {
7117 }7122 }
71187123
7119 if (is_async) {7124 if (is_async) {
7120 g->cur_is_after_return = false;
7121 g->cur_resume_block_count = 0;7125 g->cur_resume_block_count = 0;
71227126
7123 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;7127 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
test/stage1/behavior/coroutines.zig+28
...@@ -672,3 +672,31 @@ test "try in an async function with error union and non-zero-bit payload" {...@@ -672,3 +672,31 @@ test "try in an async function with error union and non-zero-bit payload" {
672 };672 };
673 S.doTheTest();673 S.doTheTest();
674}674}
675
676test "returning a const error from async function" {
677 const S = struct {
678 var frame: anyframe = undefined;
679 var ok = false;
680
681 fn doTheTest() void {
682 _ = async amain();
683 resume frame;
684 expect(ok);
685 }
686
687 fn amain() !void {
688 var download_frame = async fetchUrl(10, "a string");
689 const download_text = try await download_frame;
690
691 @panic("should not get here");
692 }
693
694 fn fetchUrl(unused: i32, url: []const u8) ![]u8 {
695 frame = @frame();
696 suspend;
697 ok = true;
698 return error.OutOfMemory;
699 }
700 };
701 S.doTheTest();
702}