diff options
-rw-r--r-- | compile.c | 5 | ||||
-rw-r--r-- | test/ruby/test_syntax.rb | 9 |
2 files changed, 14 insertions, 0 deletions
@@ -2476,6 +2476,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal goto again; } else if (IS_INSN_ID(diobj, leave)) { + INSN *pop; /* * jump LABEL * ... @@ -2483,6 +2484,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal * leave * => * leave + * pop * ... * LABEL: * leave @@ -2492,6 +2494,9 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal iobj->insn_id = BIN(leave); iobj->operand_size = 0; iobj->insn_info = diobj->insn_info; + /* adjust stack depth */ + pop = new_insn_body(iseq, diobj->insn_info.line_no, BIN(pop), 0); + ELEM_INSERT_NEXT(&iobj->link, &pop->link); goto again; } else if ((piobj = (INSN *)get_prev_insn(iobj)) != 0 && diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb index aa82f52987..8bf1627f3b 100644 --- a/test/ruby/test_syntax.rb +++ b/test/ruby/test_syntax.rb @@ -1128,6 +1128,15 @@ eom assert_equal(:begin, result) end + def test_return_in_loop + obj = Object.new + def obj.test + x = nil + return until x unless x + end + assert_nil obj.test + end + private def not_label(x) @result = x; @not_label ||= nil end |