X=0;defined?(foo(x)) dumps core

e$B1sF#$H?=$7$^$9!#e(B

defined? e$B$K0z?t$N$"$ke(B NODE_CALL e$B$rM?$($k$HMn$A$k$h$&$G$9!#e(B

$ ./ruby -e ‘x=0;defined?(foo(x))’
-e:1: – control frame ----------
c:0003 p:0021 s:0007 b:0006 l:000005 d:000005 TOP -e:1
c:0002 p:---- s:0003 b:0003 l:000002 d:000002 FINISH :inherited
c:0001 p:---- s:0001 b:-001 l:000000 d:000000 ------

– backtrace of native function call (Use addr2line) –
0x80e7f25
0x8105aa3
0x8105b6b
0x80e5fa4
0x80e67f4
0x80e6b2b
0x8059e79
0x805dda0
0x8057b80
0xb7d9fea8
0x8057aa1

[BUG] Stack consistency error (sp: 7, bp: 6)
ruby 1.9.0 (2007-11-22) [i686-linux]

e$B%"%!<%H$7$^$7$?e(B

e$BB?J,$3$s$J46$8$G$7$g$&$+!#e(B

Index: compile.c

— compile.c (revision 13997)
+++ compile.c (working copy)
@@ -2295,13 +2295,11 @@
if (node->nd_args) {
lfalse = NEW_LABEL(nd_line(node));
defined_expr(iseq, ret, node->nd_args, lfinish, Qfalse);

  •  ADD_INSNL(ret, nd_line(node), branchunless, lfalse);
    
    }
    if (!self) {
    LABEL *lcont = NEW_LABEL(nd_line(node));
  •  if (lfalse) {
    
  • ADD_INSNL(ret, nd_line(node), branchunless, lfalse);
  •  }
     defined_expr(iseq, ret, node->nd_recv, lfinish, Qfalse);
     ADD_INSNL(ret, nd_line(node), branchif, lcont);
     if (lfalse) {

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

e$B$5$C$-$N%Q%C%A$OIT40A4$Ge(B def foo;end;x=0;defined?(foo(x)) e$B$Ge(B
e$BMn$A$k$h$&$K$J$C$F$^$7$?!#$9$_$^$;$s!#e(B

e$B$b$H$N%3!<%I$,$I$&$$$&0U?^$G=q$+$l$F$$$?$N$+$h$/$o$+$i$J$$$N$G$9$,!"e(B
e$B$3$l$,@52r$G$7$g$&$+!#e(B

$ ./ruby -e ‘p defined?(foo)’
nil
$ ./ruby -e ‘p defined?(foo(x))’
nil
$ ./ruby -e ‘x=0;p defined?(foo(x))’
nil
$ ./ruby -e ‘def foo;end;p defined?(foo)’
“method”
$ ./ruby -e ‘def foo;end;p defined?(foo(x))’
nil
$ ./ruby -e ‘def foo;end;x=0;p defined?(foo(x))’
“method”

e$B:G8e$Ne(B jump e$B$H$+MW$i$J$$5$$b$7$^$9!#e(B

Index: compile.c

— compile.c (revision 13997)
+++ compile.c (working copy)
@@ -2295,13 +2295,11 @@
if (node->nd_args) {
lfalse = NEW_LABEL(nd_line(node));
defined_expr(iseq, ret, node->nd_args, lfinish, Qfalse);

  •  ADD_INSNL(ret, nd_line(node), branchunless, lfalse);
    
    }
    if (!self) {
    LABEL *lcont = NEW_LABEL(nd_line(node));
  •  if (lfalse) {
    
  • ADD_INSNL(ret, nd_line(node), branchunless, lfalse);
  •  }
     defined_expr(iseq, ret, node->nd_recv, lfinish, Qfalse);
     ADD_INSNL(ret, nd_line(node), branchif, lcont);
     if (lfalse) {
    

@@ -2319,9 +2317,8 @@
ADD_INSN(ret, nd_line(node), putself);
ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_FUNC),
ID2SYM(node->nd_mid), needstr);

  •  ADD_INSNL(ret, nd_line(node), jump, lfinish);
     if (lfalse) {
    
  • ADD_INSNL(ret, nd_line(node), branchif, lfinish);
  • ADD_LABEL(ret, lfalse);
    ADD_INSN(ret, nd_line(node), putnil);
    ADD_INSNL(ret, nd_line(node), jump, lfinish);

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:32335] Re: x=0;defined?(foo(x)) dumps core”
on Thu, 22 Nov 2007 22:42:32 +0900, “Yusuke ENDOH” [email protected]
writes:

|e$B$5$C$-$N%Q%C%A$OIT40A4$Ge(B def foo;end;x=0;defined?(foo(x)) e$B$Ge(B
|e$BMn$A$k$h$&$K$J$C$F$^$7$?!#$9$_$^$;$s!#e(B
|
|e$B$b$H$N%3!<%I$,$I$&$$$&0U?^$G=q$+$l$F$$$?$N$+$h$/$o$+$i$J$$$N$G$9$,!"e(B
|e$B$3$l$,@52r$G$7$g$&$+!#e(B
|
|$ ./ruby -e ‘p defined?(foo)’
|nil
|$ ./ruby -e ‘p defined?(foo(x))’
|nil
|$ ./ruby -e ‘x=0;p defined?(foo(x))’
|nil
|$ ./ruby -e ‘def foo;end;p defined?(foo)’
|“method”
|$ ./ruby -e ‘def foo;end;p defined?(foo(x))’
|nil
|$ ./ruby -e ‘def foo;end;x=0;p defined?(foo(x))’
|“method”

e$B$=$&$G$9$M!#%a%=%C%I$,Dj5A$5$l$F$$$F!"$9$Y$F$N0z?t$,e(Bdefined
e$B$N$H$-$KA4BN$,e(Bdefinede$B$K$J$k$H$$$&;EMM$G$9!#e(B

e$B$5$5$@$/$s!"%3%_%C%H$7$F$b$h$$$+$7$i!)e(B e$B$=$l$H$b$=$A$i$G3NG’e(B
e$B$7$^$9$+!)e(B

e$B!!$5$5$@$G$9!%e(B

Yukihiro M. wrote:

e$B$5$5$@$/$s!"%3%_%C%H$7$F$b$h$$$+$7$i!)e(B e$B$=$l$H$b$=$A$i$G3NG’e(B
e$B$7$^$9$+!)e(B

e$B!!%3%_%C%H$7$F$b$$$$$G$9$,!$$=$N:]$O%F%9%H$rIU$1$F$*$$$F$/$@$5$$!%e(B