diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-03-20 07:03:22 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-03-20 07:03:22 +0000 |
commit | bf12ea0deb5a9019bd4bbd6dfc0970d2714706e8 (patch) | |
tree | 595e9dab029eb541c80a7db14275dc8ff60581f2 /parse.y | |
parent | 85dd7bb0ef28fe4ce63641e653d92e42327b0207 (diff) |
* parse.y (stmt, primary): get rid of SEGV at empty or invalid
condition. (ruby-bugs-ja:PR#410)
* parse.y (cond_negative): negate condition node when NODE_NOT.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3585 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'parse.y')
-rw-r--r-- | parse.y | 45 |
1 files changed, 29 insertions, 16 deletions
@@ -116,6 +116,7 @@ static int quoted_term; static NODE *cond(); static NODE *logop(); +static int cond_negative(); static NODE *newline_node(); static void fixpos(); @@ -409,8 +410,7 @@ stmt : kALIAS fitem {lex_state = EXPR_FNAME;} fitem { $$ = NEW_IF(cond($3), $1, 0); fixpos($$, $3); - if (nd_type($$->nd_cond) == NODE_NOT) { - $$->nd_cond = $$->nd_cond->nd_body; + if (cond_negative(&$$->nd_cond)) { $$->nd_else = $$->nd_body; $$->nd_body = 0; } @@ -419,8 +419,7 @@ stmt : kALIAS fitem {lex_state = EXPR_FNAME;} fitem { $$ = NEW_UNLESS(cond($3), $1, 0); fixpos($$, $3); - if (nd_type($$->nd_cond) == NODE_NOT) { - $$->nd_cond = $$->nd_cond->nd_body; + if (cond_negative(&$$->nd_cond)) { $$->nd_body = $$->nd_else; $$->nd_else = 0; } @@ -433,8 +432,7 @@ stmt : kALIAS fitem {lex_state = EXPR_FNAME;} fitem else { $$ = NEW_WHILE(cond($3), $1, 1); } - if (nd_type($$->nd_cond) == NODE_NOT) { - $$->nd_cond = $$->nd_cond->nd_body; + if (cond_negative(&$$->nd_cond)) { nd_set_type($$, NODE_UNTIL); } } @@ -446,8 +444,7 @@ stmt : kALIAS fitem {lex_state = EXPR_FNAME;} fitem else { $$ = NEW_UNTIL(cond($3), $1, 1); } - if (nd_type($$->nd_cond) == NODE_NOT) { - $$->nd_cond = $$->nd_cond->nd_body; + if (cond_negative(&$$->nd_cond)) { nd_set_type($$, NODE_WHILE); } } @@ -1494,9 +1491,8 @@ primary : literal { $$ = NEW_IF(cond($2), $4, $5); fixpos($$, $2); - if (nd_type($$->nd_cond) == NODE_NOT) { + if (cond_negative(&$$->nd_cond)) { NODE *tmp = $$->nd_body; - $$->nd_cond = $$->nd_cond->nd_body; $$->nd_body = $$->nd_else; $$->nd_else = tmp; } @@ -1508,9 +1504,8 @@ primary : literal { $$ = NEW_UNLESS(cond($2), $4, $5); fixpos($$, $2); - if (nd_type($$->nd_cond) == NODE_NOT) { + if (cond_negative(&$$->nd_cond)) { NODE *tmp = $$->nd_body; - $$->nd_cond = $$->nd_cond->nd_body; $$->nd_body = $$->nd_else; $$->nd_else = tmp; } @@ -1521,8 +1516,7 @@ primary : literal { $$ = NEW_WHILE(cond($3), $6, 1); fixpos($$, $3); - if (nd_type($$->nd_cond) == NODE_NOT) { - $$->nd_cond = $$->nd_cond->nd_body; + if (cond_negative(&$$->nd_cond)) { nd_set_type($$, NODE_UNTIL); } } @@ -1532,8 +1526,7 @@ primary : literal { $$ = NEW_UNTIL(cond($3), $6, 1); fixpos($$, $3); - if (nd_type($$->nd_cond) == NODE_NOT) { - $$->nd_cond = $$->nd_cond->nd_body; + if (cond_negative(&$$->nd_cond)) { nd_set_type($$, NODE_WHILE); } } @@ -5287,6 +5280,26 @@ logop(type, left, right) return rb_node_newnode(type, left, right, 0); } +static int +cond_negative(nodep) + NODE **nodep; +{ + NODE *c = *nodep; + + if (!c) return 0; + switch (nd_type(c)) { + case NODE_NOT: + *nodep = c->nd_body; + return 1; + case NODE_NEWLINE: + if (c->nd_next && nd_type(c->nd_next) == NODE_NOT) { + c->nd_next = c->nd_next->nd_body; + return 1; + } + } + return 0; +} + static NODE * ret_args(node) NODE *node; |