commit 72805fd66e732e29637872f540371c30cb9f8b27 (tree)
parent 652efe38b40af8c2a98756e71c9e98fe339d059d
Author: Andrew Kelley <andrew@ziglang.org>
Date: Sat, 15 Feb 2020 14:16:12 -0500
fix taking address of temporary async frame
Diffstat:
2 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/src/codegen.cpp b/src/codegen.cpp
@@ -5018,6 +5018,12 @@ static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutableGen *executable, IrIns
if (!type_has_bits(instruction->base.value->type)) {
return nullptr;
}
+ if (instruction->operand->id == IrInstGenIdCall) {
+ IrInstGenCall *call = reinterpret_cast<IrInstGenCall *>(instruction->operand);
+ if (call->result_loc != nullptr) {
+ return ir_llvm_value(g, call->result_loc);
+ }
+ }
LLVMValueRef value = ir_llvm_value(g, instruction->operand);
if (handle_is_ptr(instruction->operand->value->type)) {
return value;
@@ -6533,7 +6539,7 @@ static void ir_render(CodeGen *g, ZigFn *fn_entry) {
set_debug_location(g, instruction);
}
instruction->llvm_value = ir_render_instruction(g, executable, instruction);
- if (instruction->spill != nullptr) {
+ if (instruction->spill != nullptr && instruction->llvm_value != nullptr) {
LLVMValueRef spill_ptr = ir_llvm_value(g, instruction->spill);
gen_assign_raw(g, spill_ptr, instruction->spill->value->type, instruction->llvm_value);
instruction->llvm_value = nullptr;
diff --git a/test/stage1/behavior/async_fn.zig b/test/stage1/behavior/async_fn.zig
@@ -1481,3 +1481,32 @@ test "handle defer interfering with return value spill" {
};
S.doTheTest();
}
+
+test "take address of temporary async frame" {
+ const S = struct {
+ var global_frame: anyframe = undefined;
+ var finished = false;
+
+ fn doTheTest() void {
+ _ = async asyncDoTheTest();
+ resume global_frame;
+ expect(finished);
+ }
+
+ fn asyncDoTheTest() void {
+ expect(finishIt(&async foo(10)) == 1245);
+ finished = true;
+ }
+
+ fn foo(arg: i32) i32 {
+ global_frame = @frame();
+ suspend;
+ return arg + 1234;
+ }
+
+ fn finishIt(frame: anyframe->i32) i32 {
+ return (await frame) + 1;
+ }
+ };
+ S.doTheTest();
+}