summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-03-20 07:03:22 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-03-20 07:03:22 +0000
commitbf12ea0deb5a9019bd4bbd6dfc0970d2714706e8 (patch)
tree595e9dab029eb541c80a7db14275dc8ff60581f2
parent85dd7bb0ef28fe4ce63641e653d92e42327b0207 (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
-rw-r--r--ChangeLog7
-rw-r--r--parse.y45
2 files changed, 36 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index a70d7234fd..71e23f4dc1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Thu Mar 20 16:03:18 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
+
+ * 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.
+
Thu Mar 20 10:45:29 2003 Tanaka Akira <akr@m17n.org>
* eval.c (bmcall): add volatile to avoid GC problem.
diff --git a/parse.y b/parse.y
index 1ee5633042..5a75485a1b 100644
--- a/parse.y
+++ b/parse.y
@@ -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;