ruby-changes:42532
From: akr <ko1@a...>
Date: Sat, 16 Apr 2016 00:07:43 +0900 (JST)
Subject: [ruby-changes:42532] akr:r54606 (trunk): * array.c (rb_ary_sum): Fix SEGV by [1/2r, 1].sum.
akr 2016-04-16 01:04:18 +0900 (Sat, 16 Apr 2016) New Revision: 54606 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=54606 Log: * array.c (rb_ary_sum): Fix SEGV by [1/2r, 1].sum. Modified files: trunk/ChangeLog trunk/array.c trunk/test/ruby/test_array.rb Index: array.c =================================================================== --- array.c (revision 54605) +++ array.c (revision 54606) @@ -5682,7 +5682,7 @@ rb_ary_dig(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/array.c#L5682 static VALUE rb_ary_sum(int argc, VALUE *argv, VALUE ary) { - VALUE e, v; + VALUE e, v, r; long i, n; int block_given; @@ -5695,6 +5695,7 @@ rb_ary_sum(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/array.c#L5695 return v; n = 0; + r = Qundef; for (i = 0; i < RARRAY_LEN(ary); i++) { e = RARRAY_AREF(ary, i); if (block_given) @@ -5708,22 +5709,31 @@ rb_ary_sum(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/array.c#L5709 } else if (RB_TYPE_P(e, T_BIGNUM)) v = rb_big_plus(e, v); + else if (RB_TYPE_P(e, T_RATIONAL)) { + if (r == Qundef) + r = e; + else + r = rb_rational_plus(r, e); + } else - goto not_integer; + goto not_exact; } if (n != 0) v = rb_fix_plus(LONG2FIX(n), v); + if (r != Qundef) + v = rb_rational_plus(r, v); return v; - not_integer: + not_exact: if (n != 0) v = rb_fix_plus(LONG2FIX(n), v); + if (r != Qundef) + v = rb_rational_plus(r, v); if (RB_FLOAT_TYPE_P(e)) { /* Kahan's compensated summation algorithm */ double f, c; - float_value: f = NUM2DBL(v); c = 0.0; for (; i < RARRAY_LEN(ary); i++) { @@ -5753,20 +5763,6 @@ rb_ary_sum(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/array.c#L5763 v = DBL2NUM(f); } - if (RB_TYPE_P(e, T_RATIONAL)) { - for (; i < RARRAY_LEN(ary); i++) { - e = RARRAY_AREF(ary, i); - if (block_given) - e = rb_yield(e); - if (RB_FLOAT_TYPE_P(e)) { - v = rb_to_float(v); - goto float_value; - } - v = rb_rational_plus(e, v); - } - return v; - } - for (; i < RARRAY_LEN(ary); i++) { e = RARRAY_AREF(ary, i); if (block_given) Index: ChangeLog =================================================================== --- ChangeLog (revision 54605) +++ ChangeLog (revision 54606) @@ -1,3 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sat Apr 16 01:03:32 2016 Tanaka Akira <akr@f...> + + * array.c (rb_ary_sum): Fix SEGV by [1/2r, 1].sum. + Fri Apr 15 23:52:00 2016 Kenta Murata <mrkn@m...> * rational.c (rb_rational_plus): rename from rb_rational_add Index: test/ruby/test_array.rb =================================================================== --- test/ruby/test_array.rb (revision 54605) +++ test/ruby/test_array.rb (revision 54606) @@ -2761,6 +2761,7 @@ class TestArray < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_array.rb#L2761 assert_float_equal((FIXNUM_MAX+1).to_f, [FIXNUM_MAX, 1, 0.0].sum) assert_float_equal((FIXNUM_MAX+1).to_f, [0.0, FIXNUM_MAX+1].sum) + assert_rational_equal(3/2r, [1/2r, 1].sum) assert_rational_equal(5/6r, [1/2r, 1/3r].sum) assert_equal(2.0+3.0i, [2.0, 3.0i].sum) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/