authorgravatar for paul.verigo@gmail.comPavel Verigo <paul.verigo@gmail.com> 2025-12-05 02:34:51+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-12-07 07:20:59+01:00
logcc099afca557ae427261ab0c5c733738d9d87782
tree66872dd203ddadb5c22553795b51e5535ade72a0
parenta21d9408a3ab20d90b4f410695eb598387afd8d3

sema: fix error_return_trace_index handling in zirCondBr


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

src/Sema.zig+7-3
...@@ -18486,6 +18486,9 @@ fn zirCondbr(...@@ -18486,6 +18486,9 @@ fn zirCondbr(
18486 break :blk try sub_block.addTyOp(.unwrap_errunion_err, result_ty, err_operand);18486 break :blk try sub_block.addTyOp(.unwrap_errunion_err, result_ty, err_operand);
18487 };18487 };
1848818488
18489 // Reset, this may have been updated by the then block analysis
18490 sub_block.error_return_trace_index = parent_block.error_return_trace_index;
18491
18489 const false_hint: std.builtin.BranchHint = if (err_cond != null and18492 const false_hint: std.builtin.BranchHint = if (err_cond != null and
18490 try sema.maybeErrorUnwrap(&sub_block, else_body, err_cond.?, cond_src, false))18493 try sema.maybeErrorUnwrap(&sub_block, else_body, err_cond.?, cond_src, false))
18491 h: {18494 h: {
...@@ -18961,9 +18964,10 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_...@@ -18961,9 +18964,10 @@ fn restoreErrRetIndex(sema: *Sema, start_block: *Block, src: LazySrcLoc, target_
18961 while (true) {18964 while (true) {
18962 if (block.label) |label| {18965 if (block.label) |label| {
18963 if (label.zir_block == zir_block) {18966 if (label.zir_block == zir_block) {
18964 const target_trace_index = if (block.parent) |parent_block| tgt: {18967 const target_trace_index = if (block.parent) |parent_block|
18965 break :tgt parent_block.error_return_trace_index;18968 parent_block.error_return_trace_index
18966 } else sema.error_return_trace_index_on_fn_entry;18969 else
18970 sema.error_return_trace_index_on_fn_entry;
1896718971
18968 if (start_block.error_return_trace_index != target_trace_index)18972 if (start_block.error_return_trace_index != target_trace_index)
18969 break :b target_trace_index;18973 break :b target_trace_index;
test/behavior/error.zig+19
...@@ -1090,3 +1090,22 @@ test "compare error union to error set" {...@@ -1090,3 +1090,22 @@ test "compare error union to error set" {
1090 try S.doTheTest(0);1090 try S.doTheTest(0);
1091 try comptime S.doTheTest(0);1091 try comptime S.doTheTest(0);
1092}1092}
1093
1094test "'if' ignores error via local while 'else' ignores error directly" {
1095 const S = struct {
1096 /// This function is intentionally fallible despite never returning an
1097 /// error so that it participates in error return tracing.
1098 fn testOne(cond: bool) !void {
1099 if (cond) {
1100 const result = notError();
1101 result catch {};
1102 } else {
1103 notError() catch {};
1104 }
1105 }
1106 fn notError() error{E}!void {}
1107 };
1108
1109 try S.testOne(false);
1110 try S.testOne(true);
1111}