[Bug #20217] rescue block is void only if all children are void

This commit is contained in:
Nobuyoshi Nakada 2024-01-28 11:09:55 +09:00
parent fed877c791
commit 5f733a1ae7
No known key found for this signature in database
GPG Key ID: 3582D74E1FEE4465
2 changed files with 28 additions and 0 deletions

20
parse.y
View File

@ -14305,6 +14305,26 @@ value_expr_check(struct parser_params *p, NODE *node)
}
break;
case NODE_RESCUE:
/* void only if all children are void */
vn = RNODE_RESCUE(node)->nd_head;
if (!vn || !(vn = value_expr_check(p, vn))) return NULL;
if (!void_node) void_node = vn;
for (NODE *r = RNODE_RESCUE(node)->nd_resq; r; r = RNODE_RESBODY(r)->nd_next) {
if (!nd_type_p(r, NODE_RESBODY)) {
compile_error(p, "unexpected node");
return NULL;
}
if (!(vn = value_expr_check(p, RNODE_RESBODY(r)->nd_body))) {
void_node = 0;
break;
}
if (!void_node) void_node = vn;
}
node = RNODE_RESCUE(node)->nd_else;
if (!node) return void_node;
break;
case NODE_RETURN:
case NODE_BREAK:
case NODE_NEXT:

View File

@ -1439,10 +1439,18 @@ x = __ENCODING__
"x = begin return ensure end",
"x = begin ensure return end",
"x = begin return ensure return end",
"x = begin return; rescue; return end",
"x = begin return; rescue; return; else return end",
].each do |code|
ex = assert_syntax_error(code, w)
assert_equal(1, ex.message.scan(w).size, ->{"same #{w.inspect} warning should be just once\n#{w.message}"})
end
[
"x = begin return; rescue; end",
"x = begin return; rescue; return; else end",
].each do |code|
assert_valid_syntax(code)
end
end
def eval_separately(code)