summaryrefslogtreecommitdiff
path: root/test/ruby
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-07-09 19:47:28 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-07-09 19:47:28 +0000
commit79787c183f3552198c181a1fb33e7378eb6211b8 (patch)
tree1f8a2f2c8f8e3b1e7cb565bdd7a53e044ece4b4b /test/ruby
parent11fdbaddf29d9566104439e1cf74b5cb053b741d (diff)
merge revision(s) 58262,5826: [Backport #13369]
fix TracePoint#return_value with non-local exits * vm.c: get return_value from imemo_throw_data object (THROW_DATA_VAL()). imemo_throw_data (TAG_BREAK) contains returned value. However, imemo_throw_data (TAG_BREAK) can skip several frames so that we need to use it only once (at most internal frame). To record it, we introduced THROW_DATA_CONSUMED and check it. * internal.h: define THROW_DATA_CONSUMED flag. * test/ruby/test_settracefunc.rb: add tests for [Bug #13369] * vm_insnhelper.h: add THROW_DATA_CONSUMED_P() and THROW_DATA_CONSUMED_SET(). unless File::FNM_DOTMATCH is set. (like '*/') [ruby-dev:23014] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_4@59296 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'test/ruby')
-rw-r--r--test/ruby/test_settracefunc.rb146
1 files changed, 146 insertions, 0 deletions
diff --git a/test/ruby/test_settracefunc.rb b/test/ruby/test_settracefunc.rb
index 0930a2232d..c38315263b 100644
--- a/test/ruby/test_settracefunc.rb
+++ b/test/ruby/test_settracefunc.rb
@@ -1599,4 +1599,150 @@ class TestSetTraceFunc < Test::Unit::TestCase
assert_equal [[:c_call, :itself, :alias_itself], [:c_return, :itself, :alias_itself]], events
events.clear
end
+
+ # tests for `return_value` with non-local exit [Bug #13369]
+
+ def tp_return_value mid
+ ary = []
+ TracePoint.new(:return, :b_return){|tp| ary << [tp.event, tp.method_id, tp.return_value]}.enable{
+ send mid
+ }
+ ary.pop # last b_return event is not required.
+ ary
+ end
+
+ def f_raise
+ raise
+ rescue
+ return :f_raise_return
+ end
+
+ def f_iter1
+ yield
+ return :f_iter1_return
+ end
+
+ def f_iter2
+ yield
+ return :f_iter2_return
+ end
+
+ def f_return_in_iter
+ f_iter1 do
+ f_iter2 do
+ return :f_return_in_iter_return
+ end
+ end
+ 2
+ end
+
+ def f_break_in_iter
+ f_iter1 do
+ f_iter2 do
+ break :f_break_in_iter_break
+ end
+ :f_iter1_block_value
+ end
+ :f_break_in_iter_return
+ end
+
+ def test_return_value_with_rescue
+ assert_equal [[:return, :f_raise, :f_raise_return]],
+ tp_return_value(:f_raise),
+ '[Bug #13369]'
+
+ assert_equal [[:b_return, :f_return_in_iter, nil],
+ [:return, :f_iter2, nil],
+ [:b_return, :f_return_in_iter, nil],
+ [:return, :f_iter1, nil],
+ [:return, :f_return_in_iter, :f_return_in_iter_return]],
+ tp_return_value(:f_return_in_iter),
+ '[Bug #13369]'
+
+ assert_equal [[:b_return, :f_break_in_iter, :f_break_in_iter_break],
+ [:return, :f_iter2, nil],
+ [:b_return, :f_break_in_iter, :f_iter1_block_value],
+ [:return, :f_iter1, :f_iter1_return],
+ [:return, :f_break_in_iter, :f_break_in_iter_return]],
+ tp_return_value(:f_break_in_iter),
+ '[Bug #13369]'
+ end
+
+ define_method(:f_last_defined) do
+ :f_last_defined
+ end
+
+ define_method(:f_return_defined) do
+ return :f_return_defined
+ end
+
+ define_method(:f_break_defined) do
+ return :f_break_defined
+ end
+
+ define_method(:f_raise_defined) do
+ begin
+ raise
+ rescue
+ return :f_raise_defined
+ end
+ end
+
+ define_method(:f_break_in_rescue_defined) do
+ begin
+ raise
+ rescue
+ break :f_break_in_rescue_defined
+ end
+ end
+
+ def test_return_value_with_rescue_and_defined_methods
+ assert_equal [[:b_return, :f_last_defined, :f_last_defined],
+ [:return, :f_last_defined, :f_last_defined]],
+ tp_return_value(:f_last_defined),
+ '[Bug #13369]'
+
+ assert_equal [[:b_return, :f_return_defined, nil], # current limitation
+ [:return, :f_return_defined, :f_return_defined]],
+ tp_return_value(:f_return_defined),
+ '[Bug #13369]'
+
+ assert_equal [[:b_return, :f_break_defined, nil],
+ [:return, :f_break_defined, :f_break_defined]],
+ tp_return_value(:f_break_defined),
+ '[Bug #13369]'
+
+ assert_equal [[:b_return, :f_raise_defined, nil],
+ [:return, :f_raise_defined, f_raise_defined]],
+ tp_return_value(:f_raise_defined),
+ '[Bug #13369]'
+
+ assert_equal [[:b_return, :f_break_in_rescue_defined, nil],
+ [:return, :f_break_in_rescue_defined, f_break_in_rescue_defined]],
+ tp_return_value(:f_break_in_rescue_defined),
+ '[Bug #13369]'
+ end
+
+ def f_iter
+ yield
+ end
+
+ def f_break_in_rescue
+ f_iter do
+ begin
+ raise
+ rescue
+ break :b
+ end
+ end
+ :f_break_in_rescue_return_value
+ end
+
+ def test_break_with_rescue
+ assert_equal [[:b_return, :f_break_in_rescue, :b],
+ [:return, :f_iter, nil],
+ [:return, :f_break_in_rescue, :f_break_in_rescue_return_value]],
+ tp_return_value(:f_break_in_rescue),
+ '[Bug #13369]'
+ end
end