mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
Merge pull request #18599 from dweiller/err-union-switch-err-trace
astgen: fix error return trace on error union switch
This commit is contained in:
commit
6ecf3b1ef3
3 changed files with 72 additions and 0 deletions
|
|
@ -6919,6 +6919,8 @@ fn switchExprErrUnion(
|
||||||
};
|
};
|
||||||
assert(node_tags[switch_node] == .@"switch" or node_tags[switch_node] == .switch_comma);
|
assert(node_tags[switch_node] == .@"switch" or node_tags[switch_node] == .switch_comma);
|
||||||
|
|
||||||
|
const do_err_trace = astgen.fn_block != null;
|
||||||
|
|
||||||
const extra = tree.extraData(node_datas[switch_node].rhs, Ast.Node.SubRange);
|
const extra = tree.extraData(node_datas[switch_node].rhs, Ast.Node.SubRange);
|
||||||
const case_nodes = tree.extra_data[extra.start..extra.end];
|
const case_nodes = tree.extra_data[extra.start..extra.end];
|
||||||
|
|
||||||
|
|
@ -7304,10 +7306,14 @@ fn switchExprErrUnion(
|
||||||
case_scope.instructions_top = parent_gz.instructions.items.len;
|
case_scope.instructions_top = parent_gz.instructions.items.len;
|
||||||
defer case_scope.unstack();
|
defer case_scope.unstack();
|
||||||
|
|
||||||
|
if (do_err_trace and nodeMayAppendToErrorTrace(tree, operand_node))
|
||||||
|
_ = try case_scope.addSaveErrRetIndex(.always);
|
||||||
|
|
||||||
try case_scope.addDbgBlockBegin();
|
try case_scope.addDbgBlockBegin();
|
||||||
if (dbg_var_name != .empty) {
|
if (dbg_var_name != .empty) {
|
||||||
try case_scope.addDbgVar(.dbg_var_val, dbg_var_name, dbg_var_inst);
|
try case_scope.addDbgVar(.dbg_var_val, dbg_var_name, dbg_var_inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
const target_expr_node = case.ast.target_expr;
|
const target_expr_node = case.ast.target_expr;
|
||||||
const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_info, target_expr_node);
|
const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_info, target_expr_node);
|
||||||
// check capture_scope, not err_scope to avoid false positive unused error capture
|
// check capture_scope, not err_scope to avoid false positive unused error capture
|
||||||
|
|
@ -7318,7 +7324,17 @@ fn switchExprErrUnion(
|
||||||
any_uses_err_capture = true;
|
any_uses_err_capture = true;
|
||||||
}
|
}
|
||||||
try case_scope.addDbgBlockEnd();
|
try case_scope.addDbgBlockEnd();
|
||||||
|
|
||||||
if (!parent_gz.refIsNoReturn(case_result)) {
|
if (!parent_gz.refIsNoReturn(case_result)) {
|
||||||
|
if (do_err_trace)
|
||||||
|
try restoreErrRetIndex(
|
||||||
|
&case_scope,
|
||||||
|
.{ .block = switch_block },
|
||||||
|
block_scope.break_result_info,
|
||||||
|
target_expr_node,
|
||||||
|
case_result,
|
||||||
|
);
|
||||||
|
|
||||||
_ = try case_scope.addBreakWithSrcNode(.@"break", switch_block, case_result, target_expr_node);
|
_ = try case_scope.addBreakWithSrcNode(.@"break", switch_block, case_result, target_expr_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13117,6 +13117,7 @@ fn validateErrSetSwitch(
|
||||||
.defer_err_code,
|
.defer_err_code,
|
||||||
.err_union_code,
|
.err_union_code,
|
||||||
.ret_err_value_code,
|
.ret_err_value_code,
|
||||||
|
.save_err_ret_index,
|
||||||
.restore_err_ret_index,
|
.restore_err_ret_index,
|
||||||
.is_non_err,
|
.is_non_err,
|
||||||
.ret_is_non_err,
|
.ret_is_non_err,
|
||||||
|
|
|
||||||
|
|
@ -807,4 +807,59 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
|
||||||
,
|
,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
cases.addCase(.{
|
||||||
|
.name = "error union switch with call operand",
|
||||||
|
.source =
|
||||||
|
\\pub fn main() !void {
|
||||||
|
\\ try foo();
|
||||||
|
\\ return error.TheSkyIsFalling;
|
||||||
|
\\}
|
||||||
|
\\
|
||||||
|
\\noinline fn failure() error{ Fatal, NonFatal }!void {
|
||||||
|
\\ return error.NonFatal;
|
||||||
|
\\}
|
||||||
|
\\
|
||||||
|
\\fn foo() error{Fatal}!void {
|
||||||
|
\\ return failure() catch |err| switch (err) {
|
||||||
|
\\ error.Fatal => return error.Fatal,
|
||||||
|
\\ error.NonFatal => return,
|
||||||
|
\\ };
|
||||||
|
\\}
|
||||||
|
,
|
||||||
|
.Debug = .{
|
||||||
|
.expect =
|
||||||
|
\\error: TheSkyIsFalling
|
||||||
|
\\source.zig:3:5: [address] in main (test)
|
||||||
|
\\ return error.TheSkyIsFalling;
|
||||||
|
\\ ^
|
||||||
|
\\
|
||||||
|
,
|
||||||
|
},
|
||||||
|
.ReleaseSafe = .{
|
||||||
|
.exclude_os = &.{
|
||||||
|
.windows, // TODO
|
||||||
|
.linux, // defeated by aggressive inlining
|
||||||
|
},
|
||||||
|
.expect =
|
||||||
|
\\error: TheSkyIsFalling
|
||||||
|
\\source.zig:3:5: [address] in [function]
|
||||||
|
\\ return error.TheSkyIsFalling;
|
||||||
|
\\ ^
|
||||||
|
\\
|
||||||
|
,
|
||||||
|
.error_tracing = true,
|
||||||
|
},
|
||||||
|
.ReleaseFast = .{
|
||||||
|
.expect =
|
||||||
|
\\error: TheSkyIsFalling
|
||||||
|
\\
|
||||||
|
,
|
||||||
|
},
|
||||||
|
.ReleaseSmall = .{
|
||||||
|
.expect =
|
||||||
|
\\error: TheSkyIsFalling
|
||||||
|
\\
|
||||||
|
,
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue