aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTechatrix <19954306+Techatrix@users.noreply.github.com>2024-01-16 05:51:26 +0100
committerTechatrix <19954306+Techatrix@users.noreply.github.com>2024-01-16 05:55:26 +0100
commit06410f58bd5378d5544f34dc3e87e3309cbdd332 (patch)
tree950d43fe3789619373ddc8b47236b43829a6c2a4 /src
parent8b9425c248a36afc9cd4f76707b61553b577ce14 (diff)
downloadzig-06410f58bd5378d5544f34dc3e87e3309cbdd332.tar.gz
zig-06410f58bd5378d5544f34dc3e87e3309cbdd332.zip
AstGen: properly handle ill-formed switch on error
Diffstat (limited to 'src')
-rw-r--r--src/AstGen.zig38
1 files changed, 23 insertions, 15 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig
index 3956af2ddb..6ef69e2c6b 100644
--- a/src/AstGen.zig
+++ b/src/AstGen.zig
@@ -841,13 +841,16 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE
.@"if",
=> {
const if_full = tree.fullIf(node).?;
- if (if_full.error_token) |error_token| {
- const tag = node_tags[if_full.ast.else_expr];
- if ((tag == .@"switch" or tag == .switch_comma) and
- std.mem.eql(u8, tree.tokenSlice(error_token), tree.tokenSlice(error_token + 4)))
- {
- return switchExprErrUnion(gz, scope, ri.br(), node, .@"if");
+ no_switch_on_err: {
+ const error_token = if_full.error_token orelse break :no_switch_on_err;
+ switch (node_tags[if_full.ast.else_expr]) {
+ .@"switch", .switch_comma => {},
+ else => break :no_switch_on_err,
}
+ const switch_operand = node_datas[if_full.ast.else_expr].lhs;
+ if (node_tags[switch_operand] != .identifier) break :no_switch_on_err;
+ if (!mem.eql(u8, tree.tokenSlice(error_token), tree.tokenSlice(main_tokens[switch_operand]))) break :no_switch_on_err;
+ return switchExprErrUnion(gz, scope, ri.br(), node, .@"if");
}
return ifExpr(gz, scope, ri.br(), node, if_full);
},
@@ -1026,16 +1029,21 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE
},
.@"catch" => {
const catch_token = main_tokens[node];
- const payload_token: ?Ast.TokenIndex = if (token_tags[catch_token + 1] == .pipe) blk: {
- if (token_tags.len > catch_token + 6 and
- token_tags[catch_token + 4] == .keyword_switch)
- {
- if (std.mem.eql(u8, tree.tokenSlice(catch_token + 2), tree.tokenSlice(catch_token + 6))) {
- return switchExprErrUnion(gz, scope, ri.br(), node, .@"catch");
- }
+ const payload_token: ?Ast.TokenIndex = if (token_tags[catch_token + 1] == .pipe)
+ catch_token + 2
+ else
+ null;
+ no_switch_on_err: {
+ const capture_token = payload_token orelse break :no_switch_on_err;
+ switch (node_tags[node_datas[node].rhs]) {
+ .@"switch", .switch_comma => {},
+ else => break :no_switch_on_err,
}
- break :blk catch_token + 2;
- } else null;
+ const switch_operand = node_datas[node_datas[node].rhs].lhs;
+ if (node_tags[switch_operand] != .identifier) break :no_switch_on_err;
+ if (!mem.eql(u8, tree.tokenSlice(capture_token), tree.tokenSlice(main_tokens[switch_operand]))) break :no_switch_on_err;
+ return switchExprErrUnion(gz, scope, ri.br(), node, .@"catch");
+ }
switch (ri.rl) {
.ref, .ref_coerced_ty => return orelseCatchExpr(
gz,