mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-04-26 13:01:34 +03:00
AstGen: add missing addRestoreErrRetIndex calls when handling for/while expr
Fixes #30912
This commit is contained in:
committed by
Andrew Kelley
parent
d4cac43d30
commit
36faf76fe1
@@ -6656,9 +6656,16 @@ fn whileExpr(
|
||||
.operand = undefined,
|
||||
} },
|
||||
});
|
||||
if (!continue_scope.is_comptime) {
|
||||
_ = try continue_scope.addRestoreErrRetIndex(.{ .block = continue_block }, .always, then_node);
|
||||
}
|
||||
_ = try continue_scope.addBreak(break_tag, continue_block, .void_value);
|
||||
}
|
||||
try continue_scope.setBlockBody(continue_block);
|
||||
if (!then_scope.is_comptime) {
|
||||
const cont_node = while_full.ast.cont_expr.unwrap() orelse then_node;
|
||||
_ = try then_scope.addRestoreErrRetIndex(.{ .block = cond_block }, .always, cont_node);
|
||||
}
|
||||
_ = try then_scope.addBreak(break_tag, cond_block, .void_value);
|
||||
|
||||
var else_scope = parent_gz.makeSubBlock(&cond_scope.base);
|
||||
@@ -6703,6 +6710,9 @@ fn whileExpr(
|
||||
|
||||
try checkUsed(parent_gz, &else_scope.base, sub_scope);
|
||||
if (!else_scope.endsWithNoReturn()) {
|
||||
if (!else_scope.is_comptime) {
|
||||
_ = try else_scope.addRestoreErrRetIndex(.{ .block = loop_block }, .always, else_node);
|
||||
}
|
||||
_ = try else_scope.addBreakWithSrcNode(break_tag, loop_block, else_result, else_node);
|
||||
}
|
||||
} else {
|
||||
@@ -6973,6 +6983,9 @@ fn forExpr(
|
||||
});
|
||||
|
||||
const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break";
|
||||
if (!then_scope.is_comptime) {
|
||||
_ = try then_scope.addRestoreErrRetIndex(.{ .block = cond_block }, .always, then_node);
|
||||
}
|
||||
_ = try then_scope.addBreak(break_tag, cond_block, .void_value);
|
||||
|
||||
var else_scope = parent_gz.makeSubBlock(&cond_scope.base);
|
||||
@@ -6990,6 +7003,9 @@ fn forExpr(
|
||||
_ = try addEnsureResult(&else_scope, else_result, else_node);
|
||||
}
|
||||
if (!else_scope.endsWithNoReturn()) {
|
||||
if (!else_scope.is_comptime) {
|
||||
_ = try else_scope.addRestoreErrRetIndex(.{ .block = loop_block }, .always, else_node);
|
||||
}
|
||||
_ = try else_scope.addBreakWithSrcNode(break_tag, loop_block, else_result, else_node);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -92,6 +92,132 @@ pub fn addCases(cases: *@import("tests.zig").ErrorTracesContext, os: std.Target.
|
||||
,
|
||||
});
|
||||
|
||||
cases.addCase(.{
|
||||
.name = "for loop pops error return trace",
|
||||
.source =
|
||||
\\fn foo() !void { return error.FooError; }
|
||||
\\
|
||||
\\pub fn main() !void {
|
||||
\\ for (0..2) |_| {
|
||||
\\ const f = foo();
|
||||
\\ f catch {};
|
||||
\\ } else {
|
||||
\\ const f = foo();
|
||||
\\ f catch {};
|
||||
\\ }
|
||||
\\ return error.Stop;
|
||||
\\}
|
||||
,
|
||||
.expect_error = "Stop",
|
||||
.expect_trace =
|
||||
\\source.zig:11:5: [address] in main
|
||||
\\ return error.Stop;
|
||||
\\ ^
|
||||
,
|
||||
.disable_trace_optimized = &.{
|
||||
.{ .x86_64, .windows },
|
||||
.{ .x86, .windows },
|
||||
.{ .x86_64, .macos },
|
||||
.{ .aarch64, .macos },
|
||||
},
|
||||
});
|
||||
|
||||
cases.addCase(.{
|
||||
.name = "implicit continue in for loop pops stale error return trace",
|
||||
.source =
|
||||
\\fn foo() !void { return error.FooError; }
|
||||
\\
|
||||
\\pub fn main() !void {
|
||||
\\ for (0..2) |i| {
|
||||
\\ const f = foo();
|
||||
\\ f catch {};
|
||||
\\
|
||||
\\ if (i == 1) return error.Stop;
|
||||
\\ }
|
||||
\\}
|
||||
,
|
||||
.expect_error = "Stop",
|
||||
.expect_trace =
|
||||
\\source.zig:1:18: [address] in foo
|
||||
\\fn foo() !void { return error.FooError; }
|
||||
\\ ^
|
||||
\\source.zig:8:21: [address] in main
|
||||
\\ if (i == 1) return error.Stop;
|
||||
\\ ^
|
||||
,
|
||||
.disable_trace_optimized = &.{
|
||||
.{ .x86_64, .windows },
|
||||
.{ .x86, .windows },
|
||||
.{ .x86_64, .macos },
|
||||
.{ .aarch64, .macos },
|
||||
},
|
||||
});
|
||||
|
||||
cases.addCase(.{
|
||||
.name = "while loop pops error return trace",
|
||||
.source =
|
||||
\\fn foo() !void { return error.FooError; }
|
||||
\\
|
||||
\\pub fn main() !void {
|
||||
\\ var i: usize = 0;
|
||||
\\ while (i < 2) {
|
||||
\\ const f = foo();
|
||||
\\ f catch {};
|
||||
\\ i += 1;
|
||||
\\ } else {
|
||||
\\ const f = foo();
|
||||
\\ f catch {};
|
||||
\\ }
|
||||
\\ return error.Stop;
|
||||
\\}
|
||||
,
|
||||
.expect_error = "Stop",
|
||||
.expect_trace =
|
||||
\\source.zig:13:5: [address] in main
|
||||
\\ return error.Stop;
|
||||
\\ ^
|
||||
,
|
||||
.disable_trace_optimized = &.{
|
||||
.{ .x86_64, .windows },
|
||||
.{ .x86, .windows },
|
||||
.{ .x86_64, .macos },
|
||||
.{ .aarch64, .macos },
|
||||
},
|
||||
});
|
||||
|
||||
cases.addCase(.{
|
||||
.name = "implicit continue in while loop pops stale error return trace",
|
||||
.source =
|
||||
\\fn foo() !void { return error.FooError; }
|
||||
\\
|
||||
\\pub fn main() !void {
|
||||
\\ var i: usize = 0;
|
||||
\\ while (i < 2) {
|
||||
\\ const f = foo();
|
||||
\\ f catch {};
|
||||
\\
|
||||
\\ if (i == 1) return error.Stop;
|
||||
\\ i += 1;
|
||||
\\ }
|
||||
\\}
|
||||
,
|
||||
.expect_error = "Stop",
|
||||
.expect_trace =
|
||||
\\source.zig:1:18: [address] in foo
|
||||
\\fn foo() !void { return error.FooError; }
|
||||
\\ ^
|
||||
\\source.zig:9:21: [address] in main
|
||||
\\ if (i == 1) return error.Stop;
|
||||
\\ ^
|
||||
,
|
||||
.disable_trace_optimized = &.{
|
||||
.{ .x86_64, .windows },
|
||||
.{ .x86, .windows },
|
||||
.{ .x86_64, .macos },
|
||||
.{ .aarch64, .macos },
|
||||
},
|
||||
});
|
||||
|
||||
cases.addCase(.{
|
||||
.name = "try return + handled catch/if-else",
|
||||
.source =
|
||||
|
||||
Reference in New Issue
Block a user