Commit 9e98ea552d
Changed files (2)
src
test
cases
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;
}
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");
+ }
+ };
+}