commit 9e98ea552dcf03a4a05a920c8f027d09130dd688 (tree)
parent ada441157f4a388950946e7f4db65c273f23c063
Author: Andrew Kelley <superjoe30@gmail.com>
Date: Sun, 8 Apr 2018 16:40:59 -0400
fix calling convention at callsite of zig-generated fns
Diffstat:
2 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/src/codegen.cpp b/src/codegen.cpp
@@ -1289,7 +1289,7 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
LLVMValueRef addr_ptr = LLVMBuildInBoundsGEP(g->builder, src_ptr_val, &ptr_index, 1, "");
LLVMValueRef this_addr_val = LLVMBuildLoad(g->builder, addr_ptr, "");
LLVMValueRef args[] = {dest_stack_trace_ptr, this_addr_val};
- LLVMBuildCall(g->builder, add_error_return_trace_addr_fn_val, args, 2, "");
+ ZigLLVMBuildCall(g->builder, add_error_return_trace_addr_fn_val, args, 2, get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAlways, "");
LLVMValueRef prev_frames_left = LLVMBuildLoad(g->builder, frames_left_ptr, "");
LLVMValueRef new_frames_left = LLVMBuildNUWSub(g->builder, prev_frames_left, usize_one, "");
LLVMValueRef done_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, new_frames_left, usize_zero, "");
@@ -1358,7 +1358,7 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {
LLVMValueRef return_address = LLVMBuildPtrToInt(g->builder, return_address_ptr, usize_type_ref, "");
LLVMValueRef args[] = { err_ret_trace_ptr, return_address };
- LLVMBuildCall(g->builder, add_error_return_trace_addr_fn_val, args, 2, "");
+ ZigLLVMBuildCall(g->builder, add_error_return_trace_addr_fn_val, args, 2, get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAlways, "");
LLVMBuildRetVoid(g->builder);
LLVMPositionBuilderAtEnd(g->builder, prev_block);
@@ -4387,7 +4387,7 @@ static LLVMValueRef ir_render_merge_err_ret_traces(CodeGen *g, IrExecutable *exe
LLVMValueRef dest_trace_ptr = get_cur_err_ret_trace_val(g, instruction->base.scope);
LLVMValueRef args[] = { dest_trace_ptr, src_trace_ptr };
- LLVMBuildCall(g->builder, get_merge_err_ret_traces_fn_val(g), args, 2, "");
+ ZigLLVMBuildCall(g->builder, get_merge_err_ret_traces_fn_val(g), args, 2, get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAuto, "");
return nullptr;
}
diff --git a/test/cases/coroutines.zig b/test/cases/coroutines.zig
@@ -1,4 +1,5 @@
const std = @import("std");
+const builtin = @import("builtin");
const assert = std.debug.assert;
var x: i32 = 1;
@@ -189,3 +190,30 @@ async fn failing() !void {
suspend;
return error.Fail;
}
+
+test "error return trace across suspend points" {
+ const p = nonFailing();
+ resume p;
+ const p2 = try async<std.debug.global_allocator> printTrace(p);
+ cancel p2;
+}
+
+fn nonFailing() promise->error!void {
+ return async<std.debug.global_allocator> suspendThenFail() catch unreachable;
+}
+
+async fn suspendThenFail() error!void {
+ suspend;
+ return error.Fail;
+}
+
+async fn printTrace(p: promise->error!void) void {
+ (await p) catch |e| {
+ std.debug.assert(e == error.Fail);
+ if (@errorReturnTrace()) |trace| {
+ assert(trace.index == 1);
+ } else if (builtin.mode != builtin.Mode.ReleaseFast) {
+ @panic("expected return trace");
+ }
+ };
+}