[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]