[Bug:trunk] duplicate when clauses raise strange exception

e$B1sF#$G$9!#e(B

e$BJ8;zNs$Ne(B when e$B@a$r=EJ#$5$;$k$H!“2x$7$$Nc30$,$”$,$j$^$9!#e(B

$ ruby19 -e ‘case “x”; when “x”; when “x”; end’
ruby19: method `eql?’ called on terminated object (0x826e0f0)
(NotImplementedError)

[ruby-dev:37959]
e$B$N4X78$G!“J8;zNs%j%F%i%k$,IT2D;k$K$J$C$?1F6A$N$h$&$G$9!#e(B
e$BIT2D;k$r$d$a$F$7$^$($P$H$j$”$($:2r7h$7$^$9$,!"$=$&$9$k$He(B
ObjectSpace e$B$Ge(B
when e$B@a$NJ8;zNs$r=q$-49$($i$l$F$7$^$&$h$&$K$J$j$^$9!#e(B
e$B$I$&$7$?$b$N$G$7$g$&!#e(B

e$B0J2<$Oe(B when e$B@a$NJ8;zNs$@$1IT2D;k$r$O$:$9%Q%C%A$G$9!#e(B

Index: compile.c

— compile.c (revision 22632)
+++ compile.c (working copy)
@@ -2271,7 +2271,7 @@
break;
}
case NODE_STR:

  • return node->nd_lit;
  • return rb_str_resurrect(node->nd_lit);
    }
    return Qfalse;
    }

e$B$J$+$@$G$9!#e(B

At Thu, 26 Feb 2009 00:17:40 +0900,
Yusuke ENDOH wrote in [ruby-dev:38079]:

e$BJ8;zNs$Ne(B when e$B@a$r=EJ#$5$;$k$H!“2x$7$$Nc30$,$”$,$j$^$9!#e(B

$ ruby19 -e ‘case “x”; when “x”; when “x”; end’
ruby19: method `eql?’ called on terminated object (0x826e0f0)
(NotImplementedError)

[ruby-dev:37959] e$B$N4X78$G!“J8;zNs%j%F%i%k$,IT2D;k$K$J$C$?1F6A$N$h$&$G$9!#e(B
e$BIT2D;k$r$d$a$F$7$^$($P$H$j$”$($:2r7h$7$^$9$,!"$=$&$9$k$He(B ObjectSpace e$B$Ge(B
when e$B@a$NJ8;zNs$r=q$-49$($i$l$F$7$^$&$h$&$K$J$j$^$9!#e(B
e$B$I$&$7$?$b$N$G$7$g$&!#e(B

e$B$3$l$rD4$Y$F$$$F$b$&0l$D5$$E$$$?$N$,e(B

./ruby -v -e ’
class S < String
def eql?(s)
@literal = s
super
end
attr_reader :literal
end

case a = S.new(“x”)
when “x”
end
p a.literal

ruby 1.9.2dev (2009-02-26 trunk 22637) [i386-darwin9.6.0]
-e:13:in p': methodinspect’ called on terminated object (0x11cdf8)
(NotImplementedError)
from -:12:in `’

e$B:GE,2=$5$l$J$$$H$-$K$Oe(B “x” === a
e$B$,8F$P$l$^$9$,!"$5$l$F$$$k$He(B
a.eql?(“x”)
e$B$,8F$P$l$^$9!#%j%F%i%k$r1#$=$&$H;W$&$J$i!"e(BHashe$B$r$=$Ne(B
e$B$^$^;H$&$N$O$^$:$$$H;W$$$^$9!#e(B

Index: compile.c

— compile.c (revision 22639)
+++ compile.c (working copy)
@@ -1217,4 +1217,36 @@ iseq_set_local_table(rb_iseq_t *iseq, ID
}

+static int
+cdhash_cmp(VALUE val, VALUE lit)
+{

  • if (val == lit) return 0;
  • if (SPECIAL_CONST_P(lit)) {
  • return val != lit;
  • }
  • if (SPECIAL_CONST_P(val) || BUILTIN_TYPE(val) != BUILTIN_TYPE(lit))
    {
  • return -1;
  • }
  • if (BUILTIN_TYPE(lit) == T_STRING) {
  • return rb_str_hash_cmp(lit, val);
  • }
  • return !rb_eql(lit, val);
    +}

+static int
+cdhash_hash(VALUE a)
+{

  • if (SPECIAL_CONST_P(a)) return (int)a;
  • if (TYPE(a) == T_STRING) return rb_str_hash(a);
  • {
  •    VALUE hval = rb_hash(a);
    
  • return (int)FIX2LONG(hval);
  • }
    +}

+static const struct st_hash_type cdhash_type = {

  • cdhash_cmp,
  • cdhash_hash,
    +};

/**
ruby insn object array -> raw instruction sequence
@@ -1344,4 +1376,5 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_
VALUE lits = operands[j];
VALUE map = rb_hash_new();

  •      RHASH_TBL(map)->type = &cdhash_type;
    
         for (i=0; i < RARRAY_LEN(lits); i+=2) {

e$B%A%1%C%He(B #1209 e$B$,99?7$5$l$^$7$?!#e(B (by Nobuyoshi N.)

e$B%9%F!<%?%9e(B Opene$B$+$ie(BClosede$B$KJQ99e(B
e$B?JD=e(B % 0e$B$+$ie(B100e$B$KJQ99e(B

Applied in changeset r22662.

http://redmine.ruby-lang.org/issues/show/1209