fix raise in exception with jump

add_ensure_iseq() adds ensure block to the end of
jump such as next/redo/return. However, if the rescue
cause are in the body, this rescue catches the exception
in ensure clause.

  iter do
    next
  rescue
    R
  ensure
    raise
  end

In this case, R should not be executed, but executed without this patch.

Fixes [Bug #13930]
Fixes [Bug #16618]

A part of tests are written by @jeremyevans https://github.com/ruby/ruby/pull/4291
This commit is contained in:
Koichi Sasada 2021-04-22 10:44:52 +09:00
parent 5512353d97
commit 609de71f04
Notes: git 2021-04-22 11:34:00 +09:00
3 changed files with 88 additions and 7 deletions

View file

@ -78,6 +78,66 @@ class TestException < Test::Unit::TestCase
assert(!bad)
end
def test_exception_in_ensure_with_next
string = "[ruby-core:82936] [Bug #13930]"
assert_raise_with_message(RuntimeError, string) do
lambda do
next
rescue
assert(false)
ensure
raise string
end.call
assert(false)
end
assert_raise_with_message(RuntimeError, string) do
flag = true
while flag
flag = false
begin
next
rescue
assert(false)
ensure
raise string
end
end
end
end
def test_exception_in_ensure_with_redo
string = "[ruby-core:82936] [Bug #13930]"
assert_raise_with_message(RuntimeError, string) do
i = 0
lambda do
i += 1
redo if i < 2
rescue
assert(false)
ensure
raise string
end.call
assert(false)
end
end
def test_exception_in_ensure_with_return
@string = "[ruby-core:97104] [Bug #16618]"
def self.meow
return
assert(false)
rescue
assert(false)
ensure
raise @string
end
assert_raise_with_message(RuntimeError, @string) do
meow
end
end
def test_errinfo_in_debug
bug9568 = EnvUtil.labeled_class("[ruby-core:61091] [Bug #9568]", RuntimeError) do
def to_s