@@ -5515,6 +5515,7 @@ fn zirCall(
55155515
55165516 const modifier = @intToEnum(std.builtin.CallOptions.Modifier, extra.data.flags.packed_modifier);
55175517 const ensure_result_used = extra.data.flags.ensure_result_used;
5518+ const pop_error_return_trace = extra.data.flags.pop_error_return_trace;
55185519
55195520 var func = try sema.resolveInst(extra.data.callee);
55205521 var resolved_args: []Air.Inst.Ref = undefined;
@@ -5622,7 +5623,7 @@ fn zirCall(
56225623 resolved_args[arg_index] = resolved;
56235624 }
56245625
5625- return sema.analyzeCall(block, func, func_src, call_src, modifier, ensure_result_used, resolved_args, bound_arg_src);
5626+ return sema.analyzeCall(block, func, func_src, call_src, modifier, ensure_result_used, pop_error_return_trace, resolved_args, bound_arg_src);
56265627}
56275628
56285629const GenericCallAdapter = struct {
@@ -5734,6 +5735,7 @@ fn analyzeCall(
57345735 call_src: LazySrcLoc,
57355736 modifier: std.builtin.CallOptions.Modifier,
57365737 ensure_result_used: bool,
5738+ pop_error_return_trace: bool,
57375739 uncasted_args: []const Air.Inst.Ref,
57385740 bound_arg_src: ?LazySrcLoc,
57395741) CompileError!Air.Inst.Ref {
@@ -6183,19 +6185,55 @@ fn analyzeCall(
61836185 sema.owner_func.?.calls_or_awaits_errorable_fn = true;
61846186 }
61856187
6186- try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Call).Struct.fields.len +
6187- args.len);
6188- const func_inst = try block.addInst(.{
6189- .tag = call_tag,
6190- .data = .{ .pl_op = .{
6191- .operand = func,
6192- .payload = sema.addExtraAssumeCapacity(Air.Call{
6193- .args_len = @intCast(u32, args.len),
6194- }),
6195- } },
6196- });
6197- sema.appendRefsAssumeCapacity(args);
6198- break :res func_inst;
6188+ const backend_supports_error_return_tracing = sema.mod.comp.bin_file.options.use_llvm;
6189+ const emit_error_trace_save_restore = sema.mod.comp.bin_file.options.error_return_tracing and
6190+ backend_supports_error_return_tracing and
6191+ pop_error_return_trace and func_ty_info.return_type.isError();
6192+
6193+ if (emit_error_trace_save_restore) {
6194+ // This function call is error-able (and so can generate an error trace), but AstGen determined
6195+ // that its result does not go to an error-handling operator (try/catch/return etc.). We need to
6196+ // save and restore the error trace index here, effectively "popping" the new entries immediately.
6197+
6198+ const unresolved_stack_trace_ty = try sema.getBuiltinType(block, call_src, "StackTrace");
6199+ const stack_trace_ty = try sema.resolveTypeFields(block, call_src, unresolved_stack_trace_ty);
6200+ const ptr_stack_trace_ty = try Type.Tag.single_mut_pointer.create(sema.arena, stack_trace_ty);
6201+ const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
6202+ const field_ptr = try sema.structFieldPtr(block, call_src, err_return_trace, "index", call_src, stack_trace_ty, true);
6203+
6204+ const saved_index = try sema.analyzeLoad(block, call_src, field_ptr, call_src);
6205+
6206+ try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Call).Struct.fields.len +
6207+ args.len);
6208+ const func_inst = try block.addInst(.{
6209+ .tag = call_tag,
6210+ .data = .{ .pl_op = .{
6211+ .operand = func,
6212+ .payload = sema.addExtraAssumeCapacity(Air.Call{
6213+ .args_len = @intCast(u32, args.len),
6214+ }),
6215+ } },
6216+ });
6217+ sema.appendRefsAssumeCapacity(args);
6218+
6219+ try sema.storePtr2(block, call_src, field_ptr, call_src, saved_index, call_src, .store);
6220+
6221+ break :res func_inst;
6222+ } else {
6223+ try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Call).Struct.fields.len +
6224+ args.len);
6225+ const func_inst = try block.addInst(.{
6226+ .tag = call_tag,
6227+ .data = .{ .pl_op = .{
6228+ .operand = func,
6229+ .payload = sema.addExtraAssumeCapacity(Air.Call{
6230+ .args_len = @intCast(u32, args.len),
6231+ }),
6232+ } },
6233+ });
6234+ sema.appendRefsAssumeCapacity(args);
6235+ break :res func_inst;
6236+ }
61996237 };
62006238
62016239 if (ensure_result_used) {
@@ -10400,7 +10438,7 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op
1040010438 const panic_fn = try sema.getBuiltin(block, src, "panicUnwrapError");
1040110439 const err_return_trace = try sema.getErrorReturnTrace(block, src);
1040210440 const args: [2]Air.Inst.Ref = .{ err_return_trace, operand };
10403- _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, &args, null);
10441+ _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, false, &args, null);
1040410442 return true;
1040510443 },
1040610444 .panic => {
@@ -10411,7 +10449,7 @@ fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, op
1041110449 const panic_fn = try sema.getBuiltin(block, src, "panic");
1041210450 const err_return_trace = try sema.getErrorReturnTrace(block, src);
1041310451 const args: [2]Air.Inst.Ref = .{ msg_inst, err_return_trace };
10414- _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, &args, null);
10452+ _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, false, &args, null);
1041510453 return true;
1041610454 },
1041710455 else => unreachable,
@@ -15549,7 +15587,7 @@ fn retWithErrTracing(
1554915587 const args: [1]Air.Inst.Ref = .{err_return_trace};
1555015588
1555115589 if (!need_check) {
15552- _ = try sema.analyzeCall(block, return_err_fn, src, src, .never_inline, false, &args, null);
15590+ _ = try sema.analyzeCall(block, return_err_fn, src, src, .never_inline, false, false, &args, null);
1555315591 _ = try block.addUnOp(ret_tag, operand);
1555415592 return always_noreturn;
1555515593 }
@@ -15560,7 +15598,7 @@ fn retWithErrTracing(
1556015598
1556115599 var else_block = block.makeSubBlock();
1556215600 defer else_block.instructions.deinit(gpa);
15563- _ = try sema.analyzeCall(&else_block, return_err_fn, src, src, .never_inline, false, &args, null);
15601+ _ = try sema.analyzeCall(&else_block, return_err_fn, src, src, .never_inline, false, false, &args, null);
1556415602 _ = try else_block.addUnOp(ret_tag, operand);
1556515603
1556615604 try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).Struct.fields.len +
@@ -19674,7 +19712,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1967419712 }
1967519713 }
1967619714 const ensure_result_used = extra.flags.ensure_result_used;
19677- return sema.analyzeCall(block, func, func_src, call_src, modifier, ensure_result_used, resolved_args, bound_arg_src);
19715+ return sema.analyzeCall(block, func, func_src, call_src, modifier, ensure_result_used, false, resolved_args, bound_arg_src);
1967819716}
1967919717
1968019718fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
@@ -21092,7 +21130,7 @@ fn panicWithMsg(
2109221130 Value.@"null",
2109321131 );
2109421132 const args: [2]Air.Inst.Ref = .{ msg_inst, null_stack_trace };
21095- _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, &args, null);
21133+ _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, false, &args, null);
2109621134 return always_noreturn;
2109721135}
2109821136
@@ -21133,7 +21171,7 @@ fn panicUnwrapError(
2113321171 const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand);
2113421172 const err_return_trace = try sema.getErrorReturnTrace(&fail_block, src);
2113521173 const args: [2]Air.Inst.Ref = .{ err_return_trace, err };
21136- _ = try sema.analyzeCall(&fail_block, panic_fn, src, src, .auto, false, &args, null);
21174+ _ = try sema.analyzeCall(&fail_block, panic_fn, src, src, .auto, false, false, &args, null);
2113721175 }
2113821176 }
2113921177 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);
@@ -21174,7 +21212,7 @@ fn panicIndexOutOfBounds(
2117421212 } else {
2117521213 const panic_fn = try sema.getBuiltin(&fail_block, src, "panicOutOfBounds");
2117621214 const args: [2]Air.Inst.Ref = .{ index, len };
21177- _ = try sema.analyzeCall(&fail_block, panic_fn, src, src, .auto, false, &args, null);
21215+ _ = try sema.analyzeCall(&fail_block, panic_fn, src, src, .auto, false, false, &args, null);
2117821216 }
2117921217 }
2118021218 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);
@@ -21216,7 +21254,7 @@ fn panicSentinelMismatch(
2121621254 else {
2121721255 const panic_fn = try sema.getBuiltin(parent_block, src, "checkNonScalarSentinel");
2121821256 const args: [2]Air.Inst.Ref = .{ expected_sentinel, actual_sentinel };
21219- _ = try sema.analyzeCall(parent_block, panic_fn, src, src, .auto, false, &args, null);
21257+ _ = try sema.analyzeCall(parent_block, panic_fn, src, src, .auto, false, false, &args, null);
2122021258 return;
2122121259 };
2122221260 const gpa = sema.gpa;
@@ -21245,7 +21283,7 @@ fn panicSentinelMismatch(
2124521283 } else {
2124621284 const panic_fn = try sema.getBuiltin(&fail_block, src, "panicSentinelMismatch");
2124721285 const args: [2]Air.Inst.Ref = .{ expected_sentinel, actual_sentinel };
21248- _ = try sema.analyzeCall(&fail_block, panic_fn, src, src, .auto, false, &args, null);
21286+ _ = try sema.analyzeCall(&fail_block, panic_fn, src, src, .auto, false, false, &args, null);
2124921287 }
2125021288 }
2125121289 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);
0 commit comments