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...@@ -5018,6 +5018,12 @@ static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutableGen *executable, IrIns
5018 if (!type_has_bits(instruction->base.value->type)) {5018 if (!type_has_bits(instruction->base.value->type)) {
5019 return nullptr;5019 return nullptr;
5020 }5020 }
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 }
5021 LLVMValueRef value = ir_llvm_value(g, instruction->operand);5027 LLVMValueRef value = ir_llvm_value(g, instruction->operand);
5022 if (handle_is_ptr(instruction->operand->value->type)) {5028 if (handle_is_ptr(instruction->operand->value->type)) {
5023 return value;5029 return value;
...@@ -6533,7 +6539,7 @@ static void ir_render(CodeGen *g, ZigFn *fn_entry) {...@@ -6533,7 +6539,7 @@ static void ir_render(CodeGen *g, ZigFn *fn_entry) {
6533 set_debug_location(g, instruction);6539 set_debug_location(g, instruction);
6534 }6540 }
6535 instruction->llvm_value = ir_render_instruction(g, executable, instruction);6541 instruction->llvm_value = ir_render_instruction(g, executable, instruction);
6536 if (instruction->spill != nullptr) {6542 if (instruction->spill != nullptr && instruction->llvm_value != nullptr) {
6537 LLVMValueRef spill_ptr = ir_llvm_value(g, instruction->spill);6543 LLVMValueRef spill_ptr = ir_llvm_value(g, instruction->spill);
6538 gen_assign_raw(g, spill_ptr, instruction->spill->value->type, instruction->llvm_value);6544 gen_assign_raw(g, spill_ptr, instruction->spill->value->type, instruction->llvm_value);
6539 instruction->llvm_value = nullptr;6545 instruction->llvm_value = nullptr;
test/stage1/behavior/async_fn.zig+29
...@@ -1481,3 +1481,32 @@ test "handle defer interfering with return value spill" {...@@ -1481,3 +1481,32 @@ test "handle defer interfering with return value spill" {
1481 };1481 };
1482 S.doTheTest();1482 S.doTheTest();
1483}1483}
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}