Bug #11804
52931 以降、caseでInfinityを使用するとFloatDomainErrorが発生する
Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 2.3.0dev (2015-12-11 trunk 53027) [x86_64-darwin14]
Description
以下のようなケースです。
def test_infinity
inf = 1.0/0.0
result = case inf
when true then 1
when false then 0
else
inf.to_i rescue nil
end
assert_nil result
end
52930の場合
# Running tests: Finished tests in 0.136572s, 51.2550 tests/s, 314.8522 assertions/s. 7 tests, 43 assertions, 0 failures, 0 errors, 0 skips
52931の場合
[4/7] TestCase#test_infinity = 0.00 s 1) Error: TestCase#test_infinity: FloatDomainError: Infinity ruby/test/ruby/test_case.rb:156:in `test_infinity' Finished tests in 0.135196s, 51.7767 tests/s, 310.6601 assertions/s. 7 tests, 42 assertions, 0 failures, 1 errors, 0 skips
なおwhen
のあとがStringのみのケースだと2.2.3でも例外が発生します。
irb(main):001:0> RUBY_VERSION
=> "2.2.3"
irb(main):002:0> inf = 1.0/0.0
=> Infinity
irb(main):003:0>
irb(main):004:0* result = case inf
irb(main):005:1> when 'str' then :string
irb(main):006:1> else
irb(main):007:1* inf.to_i rescue nil
irb(main):008:1> end
FloatDomainError: Infinity
from (irb):4
from .rbenv/versions/2.2.3/bin/irb:11:in `<main>'
Updated by yui-knk (Kaneko Yuichiro) about 5 years ago
- Subject changed from 52693 以降、caseでInfinityを使用するとFloatDomainErrorが発生する to 52931 以降、caseでInfinityを使用するとFloatDomainErrorが発生する
Updated by normalperson (Eric Wong) about 5 years ago
- Backport changed from 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN to 2.0.0: REQUIRED, 2.1: REQUIRED, 2.2: REQUIRED
Not a new bug, actually; just easier to find since r52931
(Sorry I don't know Japanese, but was able to understand the Ruby at least).
This will need to be backported.
inf = 1.0/0.0 result = case inf when 1 then 1 when 0 then 0 else inf.to_i rescue nil end p result diff --git a/insns.def b/insns.def index 3c185bd..df65aa8 100644 --- a/insns.def +++ b/insns.def @@ -1262,7 +1262,7 @@ opt_case_dispatch switch(TYPE(key)) { case T_FLOAT: { double ival; - if (modf(RFLOAT_VALUE(key), &ival) == 0.0) { + if (modf(RFLOAT_VALUE(key), &ival) == 0.0 && !isinf(ival)) { key = FIXABLE(ival) ? LONG2FIX((long)ival) : rb_dbl2big(ival); } }
Updated by Anonymous about 5 years ago
- Status changed from Open to Closed
Applied in changeset r53039.
insns.def (opt_case_dispatch): avoid converting Infinity
Infinity cannot be written as an optimizable literal,
so it can never match a key in a CDHASH.
Avoid converting it to prevent FloatDomainError.
- insns.def (opt_case_dispatch): avoid converting Infinity
- test/ruby/test_optimization.rb (test_opt_case_dispatch_inf): new [ruby-dev:49423] [Bug #11804]
Updated by nagachika (Tomoyuki Chikanaga) about 5 years ago
- Backport changed from 2.0.0: REQUIRED, 2.1: REQUIRED, 2.2: REQUIRED to 2.0.0: REQUIRED, 2.1: REQUIRED, 2.2: DONE
Backported into ruby_2_2
branch at r53040.
Updated by yui-knk (Kaneko Yuichiro) about 5 years ago
Thanks for your patch (Eric) :)
Updated by usa (Usaku NAKAMURA) about 5 years ago
- Backport changed from 2.0.0: REQUIRED, 2.1: REQUIRED, 2.2: DONE to 2.0.0: REQUIRED, 2.1: DONE, 2.2: DONE
ruby_2_1 r53147 merged revision(s) 53039.