mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Fix wrong "void value expression" error
* parse.y (value_expr_check): if either of `then` or `else` statements is not a void value expression, the whole `if` is not also a void value expression. [Bug #15932]
This commit is contained in:
parent
09a846085c
commit
01b3a38043
2 changed files with 28 additions and 12 deletions
34
parse.y
34
parse.y
|
@ -10521,10 +10521,10 @@ node_assign(struct parser_params *p, NODE *lhs, NODE *rhs, const YYLTYPE *loc)
|
||||||
return lhs;
|
return lhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static NODE *
|
||||||
value_expr_gen(struct parser_params *p, NODE *node)
|
value_expr_check(struct parser_params *p, NODE *node)
|
||||||
{
|
{
|
||||||
int cond = 0;
|
NODE *void_node = 0, *vn;
|
||||||
|
|
||||||
if (!node) {
|
if (!node) {
|
||||||
rb_warning0("empty expression");
|
rb_warning0("empty expression");
|
||||||
|
@ -10536,9 +10536,7 @@ value_expr_gen(struct parser_params *p, NODE *node)
|
||||||
case NODE_NEXT:
|
case NODE_NEXT:
|
||||||
case NODE_REDO:
|
case NODE_REDO:
|
||||||
case NODE_RETRY:
|
case NODE_RETRY:
|
||||||
if (!cond) yyerror1(&node->nd_loc, "void value expression");
|
return void_node ? void_node : node;
|
||||||
/* or "control never reach"? */
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
case NODE_BLOCK:
|
case NODE_BLOCK:
|
||||||
while (node->nd_next) {
|
while (node->nd_next) {
|
||||||
|
@ -10561,14 +10559,15 @@ value_expr_gen(struct parser_params *p, NODE *node)
|
||||||
node = node->nd_body;
|
node = node->nd_body;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!value_expr(node->nd_body)) return FALSE;
|
vn = value_expr_check(p, node->nd_body);
|
||||||
|
if (!vn) return NULL;
|
||||||
|
if (!void_node) void_node = vn;
|
||||||
node = node->nd_else;
|
node = node->nd_else;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_AND:
|
case NODE_AND:
|
||||||
case NODE_OR:
|
case NODE_OR:
|
||||||
cond = 1;
|
node = node->nd_1st;
|
||||||
node = node->nd_2nd;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NODE_LASGN:
|
case NODE_LASGN:
|
||||||
|
@ -10576,16 +10575,27 @@ value_expr_gen(struct parser_params *p, NODE *node)
|
||||||
case NODE_DASGN_CURR:
|
case NODE_DASGN_CURR:
|
||||||
case NODE_MASGN:
|
case NODE_MASGN:
|
||||||
mark_lvar_used(p, node);
|
mark_lvar_used(p, node);
|
||||||
return TRUE;
|
return NULL;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return TRUE;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
value_expr_gen(struct parser_params *p, NODE *node)
|
||||||
|
{
|
||||||
|
NODE *void_node = value_expr_check(p, node);
|
||||||
|
if (void_node) {
|
||||||
|
yyerror1(&void_node->nd_loc, "void value expression");
|
||||||
|
/* or "control never reach"? */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
static void
|
static void
|
||||||
void_expr(struct parser_params *p, NODE *node)
|
void_expr(struct parser_params *p, NODE *node)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1388,6 +1388,12 @@ eom
|
||||||
assert_syntax_error('a|>-b', /unexpected '-'/)
|
assert_syntax_error('a|>-b', /unexpected '-'/)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_value_expr_in_condition
|
||||||
|
mesg = /void value expression/
|
||||||
|
assert_syntax_error("tap {a = (true ? next : break)}", mesg)
|
||||||
|
assert_valid_syntax("tap {a = (true ? true : break)}")
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def not_label(x) @result = x; @not_label ||= nil end
|
def not_label(x) @result = x; @not_label ||= nil end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue