aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-02-07 22:48:31 -0500
committerAndrew Kelley <andrew@ziglang.org>2020-02-07 22:48:31 -0500
commit877f39d2270a648fac2dda048bf972b7cc9a1430 (patch)
tree7ad7440d1e8721d7859b3b7f0a986afb3e7cb11e /src/codegen.cpp
parent39ee1f4b97053cdc080ddf3562cefc6bed2071a8 (diff)
downloadzig-877f39d2270a648fac2dda048bf972b7cc9a1430.tar.gz
zig-877f39d2270a648fac2dda048bf972b7cc9a1430.zip
fix async function call resolves target fn frame
Diffstat (limited to 'src/codegen.cpp')
-rw-r--r--src/codegen.cpp15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 1c677389c1..5b87292929 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -4059,6 +4059,8 @@ static void gen_init_stack_trace(CodeGen *g, LLVMValueRef trace_field_ptr, LLVMV
}
static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrInstGenCall *instruction) {
+ Error err;
+
LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
LLVMValueRef fn_val;
@@ -4089,6 +4091,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
ZigList<ZigType *> gen_param_types = {};
LLVMValueRef result_loc = instruction->result_loc ? ir_llvm_value(g, instruction->result_loc) : nullptr;
LLVMValueRef zero = LLVMConstNull(usize_type_ref);
+ bool need_frame_ptr_ptr_spill = false;
LLVMValueRef frame_result_loc_uncasted = nullptr;
LLVMValueRef frame_result_loc;
LLVMValueRef awaiter_init_val;
@@ -4127,14 +4130,17 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
LLVMPositionBuilderAtEnd(g->builder, ok_block);
}
+ need_frame_ptr_ptr_spill = true;
LLVMValueRef frame_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_slice_ptr, slice_ptr_index, "");
LLVMValueRef frame_ptr = LLVMBuildLoad(g->builder, frame_ptr_ptr, "");
if (instruction->fn_entry == nullptr) {
ZigType *anyframe_type = get_any_frame_type(g, src_return_type);
frame_result_loc = LLVMBuildBitCast(g->builder, frame_ptr, get_llvm_type(g, anyframe_type), "");
} else {
- ZigType *ptr_frame_type = get_pointer_to_type(g,
- get_fn_frame_type(g, instruction->fn_entry), false);
+ ZigType *frame_type = get_fn_frame_type(g, instruction->fn_entry);
+ if ((err = type_resolve(g, frame_type, ResolveStatusLLVMFull)))
+ codegen_report_errors_and_exit(g);
+ ZigType *ptr_frame_type = get_pointer_to_type(g, frame_type, false);
frame_result_loc = LLVMBuildBitCast(g->builder, frame_ptr,
get_llvm_type(g, ptr_frame_type), "");
}
@@ -4405,6 +4411,11 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
}
}
+ if (need_frame_ptr_ptr_spill) {
+ LLVMValueRef frame_slice_ptr = ir_llvm_value(g, instruction->new_stack);
+ LLVMValueRef frame_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_slice_ptr, slice_ptr_index, "");
+ frame_result_loc_uncasted = LLVMBuildLoad(g->builder, frame_ptr_ptr, "");
+ }
if (frame_result_loc_uncasted != nullptr && instruction->fn_entry != nullptr) {
// Instead of a spill, we do the bitcast again. The uncasted LLVM IR instruction will
// be an Alloca from the entry block, so it does not need to be spilled.