authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-15 14:16:12-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-16 01:44:49-05:00
log72805fd66e732e29637872f540371c30cb9f8b27
treea806bc971b52cb833c210a17f87e3eebb6f4dd2a
parent652efe38b40af8c2a98756e71c9e98fe339d059d
signaturelock-open Commit is signed but in an unrecognized format.

fix taking address of temporary async frame


2 files changed, 36 insertions(+), 1 deletions(-)

src/codegen.cpp+7-1
......@@ -5018,6 +5018,12 @@ static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutableGen *executable, IrIns
50185018 if (!type_has_bits(instruction->base.value->type)) {
50195019 return nullptr;
50205020 }
5021 if (instruction->operand->id == IrInstGenIdCall) {
5022 IrInstGenCall *call = reinterpret_cast<IrInstGenCall *>(instruction->operand);
5023 if (call->result_loc != nullptr) {
5024 return ir_llvm_value(g, call->result_loc);
5025 }
5026 }
50215027 LLVMValueRef value = ir_llvm_value(g, instruction->operand);
50225028 if (handle_is_ptr(instruction->operand->value->type)) {
50235029 return value;
......@@ -6533,7 +6539,7 @@ static void ir_render(CodeGen *g, ZigFn *fn_entry) {
65336539 set_debug_location(g, instruction);
65346540 }
65356541 instruction->llvm_value = ir_render_instruction(g, executable, instruction);
6536 if (instruction->spill != nullptr) {
6542 if (instruction->spill != nullptr && instruction->llvm_value != nullptr) {
65376543 LLVMValueRef spill_ptr = ir_llvm_value(g, instruction->spill);
65386544 gen_assign_raw(g, spill_ptr, instruction->spill->value->type, instruction->llvm_value);
65396545 instruction->llvm_value = nullptr;
test/stage1/behavior/async_fn.zig+29
......@@ -1481,3 +1481,32 @@ test "handle defer interfering with return value spill" {
14811481 };
14821482 S.doTheTest();
14831483}
1484
1485test "take address of temporary async frame" {
1486 const S = struct {
1487 var global_frame: anyframe = undefined;
1488 var finished = false;
1489
1490 fn doTheTest() void {
1491 _ = async asyncDoTheTest();
1492 resume global_frame;
1493 expect(finished);
1494 }
1495
1496 fn asyncDoTheTest() void {
1497 expect(finishIt(&async foo(10)) == 1245);
1498 finished = true;
1499 }
1500
1501 fn foo(arg: i32) i32 {
1502 global_frame = @frame();
1503 suspend;
1504 return arg + 1234;
1505 }
1506
1507 fn finishIt(frame: anyframe->i32) i32 {
1508 return (await frame) + 1;
1509 }
1510 };
1511 S.doTheTest();
1512}