authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-08 16:40:59-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-08 16:40:59-04:00
log9e98ea552dcf03a4a05a920c8f027d09130dd688
treefa726bca66597c3734038ab2cb41cfd6990f5a97
parentada441157f4a388950946e7f4db65c273f23c063

fix calling convention at callsite of zig-generated fns


2 files changed, 31 insertions(+), 3 deletions(-)

src/codegen.cpp+3-3
...@@ -1289,7 +1289,7 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {...@@ -1289,7 +1289,7 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
1289 LLVMValueRef addr_ptr = LLVMBuildInBoundsGEP(g->builder, src_ptr_val, &ptr_index, 1, "");1289 LLVMValueRef addr_ptr = LLVMBuildInBoundsGEP(g->builder, src_ptr_val, &ptr_index, 1, "");
1290 LLVMValueRef this_addr_val = LLVMBuildLoad(g->builder, addr_ptr, "");1290 LLVMValueRef this_addr_val = LLVMBuildLoad(g->builder, addr_ptr, "");
1291 LLVMValueRef args[] = {dest_stack_trace_ptr, this_addr_val};1291 LLVMValueRef args[] = {dest_stack_trace_ptr, this_addr_val};
1292 LLVMBuildCall(g->builder, add_error_return_trace_addr_fn_val, args, 2, "");1292 ZigLLVMBuildCall(g->builder, add_error_return_trace_addr_fn_val, args, 2, get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAlways, "");
1293 LLVMValueRef prev_frames_left = LLVMBuildLoad(g->builder, frames_left_ptr, "");1293 LLVMValueRef prev_frames_left = LLVMBuildLoad(g->builder, frames_left_ptr, "");
1294 LLVMValueRef new_frames_left = LLVMBuildNUWSub(g->builder, prev_frames_left, usize_one, "");1294 LLVMValueRef new_frames_left = LLVMBuildNUWSub(g->builder, prev_frames_left, usize_one, "");
1295 LLVMValueRef done_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, new_frames_left, usize_zero, "");1295 LLVMValueRef done_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, new_frames_left, usize_zero, "");
...@@ -1358,7 +1358,7 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {...@@ -1358,7 +1358,7 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {
1358 LLVMValueRef return_address = LLVMBuildPtrToInt(g->builder, return_address_ptr, usize_type_ref, "");1358 LLVMValueRef return_address = LLVMBuildPtrToInt(g->builder, return_address_ptr, usize_type_ref, "");
13591359
1360 LLVMValueRef args[] = { err_ret_trace_ptr, return_address };1360 LLVMValueRef args[] = { err_ret_trace_ptr, return_address };
1361 LLVMBuildCall(g->builder, add_error_return_trace_addr_fn_val, args, 2, "");1361 ZigLLVMBuildCall(g->builder, add_error_return_trace_addr_fn_val, args, 2, get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAlways, "");
1362 LLVMBuildRetVoid(g->builder);1362 LLVMBuildRetVoid(g->builder);
13631363
1364 LLVMPositionBuilderAtEnd(g->builder, prev_block);1364 LLVMPositionBuilderAtEnd(g->builder, prev_block);
...@@ -4387,7 +4387,7 @@ static LLVMValueRef ir_render_merge_err_ret_traces(CodeGen *g, IrExecutable *exe...@@ -4387,7 +4387,7 @@ static LLVMValueRef ir_render_merge_err_ret_traces(CodeGen *g, IrExecutable *exe
4387 LLVMValueRef dest_trace_ptr = get_cur_err_ret_trace_val(g, instruction->base.scope);4387 LLVMValueRef dest_trace_ptr = get_cur_err_ret_trace_val(g, instruction->base.scope);
43884388
4389 LLVMValueRef args[] = { dest_trace_ptr, src_trace_ptr };4389 LLVMValueRef args[] = { dest_trace_ptr, src_trace_ptr };
4390 LLVMBuildCall(g->builder, get_merge_err_ret_traces_fn_val(g), args, 2, "");4390 ZigLLVMBuildCall(g->builder, get_merge_err_ret_traces_fn_val(g), args, 2, get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAuto, "");
4391 return nullptr;4391 return nullptr;
4392}4392}
43934393
test/cases/coroutines.zig+28
...@@ -1,4 +1,5 @@...@@ -1,4 +1,5 @@
1const std = @import("std");1const std = @import("std");
2const builtin = @import("builtin");
2const assert = std.debug.assert;3const assert = std.debug.assert;
34
4var x: i32 = 1;5var x: i32 = 1;
...@@ -189,3 +190,30 @@ async fn failing() !void {...@@ -189,3 +190,30 @@ async fn failing() !void {
189 suspend;190 suspend;
190 return error.Fail;191 return error.Fail;
191}192}
193
194test "error return trace across suspend points" {
195 const p = nonFailing();
196 resume p;
197 const p2 = try async<std.debug.global_allocator> printTrace(p);
198 cancel p2;
199}
200
201fn nonFailing() promise->error!void {
202 return async<std.debug.global_allocator> suspendThenFail() catch unreachable;
203}
204
205async fn suspendThenFail() error!void {
206 suspend;
207 return error.Fail;
208}
209
210async fn printTrace(p: promise->error!void) void {
211 (await p) catch |e| {
212 std.debug.assert(e == error.Fail);
213 if (@errorReturnTrace()) |trace| {
214 assert(trace.index == 1);
215 } else if (builtin.mode != builtin.Mode.ReleaseFast) {
216 @panic("expected return trace");
217 }
218 };
219}