summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--compile.c46
-rw-r--r--test/ruby/test_case.rb20
3 files changed, 43 insertions, 28 deletions
diff --git a/ChangeLog b/ChangeLog
index 712270206a..710396c4bc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Sat Apr 17 09:19:27 2010 wanabe <s.wanabe@gmail.com>
+
+ * compile.c (iseq_compile_each): fix splat condition in NODE_WHEN.
+ [Bug #2226]
+
Sat Apr 17 08:57:41 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>
* lib/net/smtp.rb (Net::SMTP#rcptto_list): continue when at least
diff --git a/compile.c b/compile.c
index 64411f90a0..e96e34da5b 100644
--- a/compile.c
+++ b/compile.c
@@ -3129,40 +3129,30 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
ADD_INSNL(body_seq, nd_line(node), jump, endlabel);
vals = node->nd_head;
- if (vals && nd_type(vals) == NODE_ARRAY) {
+ if (!vals) {
+ rb_bug("NODE_WHEN: must be NODE_ARRAY, but 0");
+ }
+ switch (nd_type(vals)) {
+ case NODE_ARRAY:
while (vals) {
val = vals->nd_head;
COMPILE(ret, "when2", val);
ADD_INSNL(ret, nd_line(val), branchif, l1);
vals = vals->nd_next;
}
- }
- else if (nd_type(vals) == NODE_SPLAT ||
- nd_type(vals) == NODE_ARGSCAT ||
- nd_type(vals) == NODE_ARGSPUSH) {
-
- NODE *val = vals->nd_head;
-
- if (nd_type(vals) == NODE_ARGSCAT || nd_type(vals) == NODE_ARGSPUSH) {
- NODE *vs = vals->nd_head;
- val = vals->nd_body;
-
- while (vs) {
- NODE* val = vs->nd_head;
- COMPILE(ret, "when/argscat", val);
- ADD_INSNL(ret, nd_line(val), branchif, l1);
- vs = vs->nd_next;
- }
- }
-
- ADD_INSN(ret, nd_line(val), putnil);
- COMPILE(ret, "when2/splat", val);
- ADD_INSN1(ret, nd_line(val), checkincludearray, Qfalse);
- ADD_INSN(ret, nd_line(val), pop);
- ADD_INSNL(ret, nd_line(val), branchif, l1);
- }
- else {
- rb_bug("err");
+ break;
+ case NODE_SPLAT:
+ case NODE_ARGSCAT:
+ case NODE_ARGSPUSH:
+ ADD_INSN(ret, nd_line(vals), putnil);
+ COMPILE(ret, "when2/cond splat", vals);
+ ADD_INSN1(ret, nd_line(vals), checkincludearray, Qfalse);
+ ADD_INSN(ret, nd_line(vals), pop);
+ ADD_INSNL(ret, nd_line(vals), branchif, l1);
+ break;
+ default:
+ rb_bug("NODE_WHEN: unknown node (%s)",
+ ruby_node_name(nd_type(vals)));
}
node = node->nd_next;
}
diff --git a/test/ruby/test_case.rb b/test/ruby/test_case.rb
index c4bffa811f..98498dada6 100644
--- a/test/ruby/test_case.rb
+++ b/test/ruby/test_case.rb
@@ -53,6 +53,26 @@ class TestCase < Test::Unit::TestCase
else
assert(false)
end
+
+ case
+ when *[], false
+ assert(false)
+ else
+ assert(true)
+ end
+
+ case
+ when *false, []
+ assert(true)
+ else
+ assert(false)
+ end
+
+ assert_raise(NameError) do
+ case
+ when false, *x, false
+ end
+ end
end
def test_deoptimization