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

ruby-changes:57537

From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Thu, 5 Sep 2019 14:30:39 +0900 (JST)
Subject: [ruby-changes:57537] 41bc766763 (master): interesting (but annoying) tidbit warning suppressed

https://git.ruby-lang.org/ruby.git/commit/?id=41bc766763

From 41bc766763dba63ae2529f2f9070b8e26399745c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?=
 <shyouhei@r...>
Date: Thu, 5 Sep 2019 14:29:11 +0900
Subject: interesting (but annoying) tidbit warning suppressed

This changeset is to suppress clang's -Wimplicit-int-float-conversion
warning.

In 64 bit signed long and IEEE 754 double combination (== almost
everyone these days), LONG_MAX is 9,223,372,036,854,775,807.  This
value is _not_ exactly representable by double.  The nearest value
that a double can represnt is 9,223,372,036,854,775,808. It is one
greater than LONG_MAX.  Let's call this value the "x".

The expression `LONG_MAX < yi` is a long versus double comparison.
According to ISO/IEC 9899:1999 Section 6.3.1.8 (that defines the
"usual rithmetic conversions"), The long value must first be casted
into double.  Because FLT_ROUNDS is typically 1 ("round to the
nearest" mode), the conversion yields the "x" value shown above.  So
the comparison is in fact `x < yi`.

This comparison is false for yi == x situation, i.e. yi is still
bigger than LONG_MAX.  On such situation the `yn = (long)yi;`
statement that appear several lines below renders underfined
behaviour, as per ISO/IEC 9899:1999 Section 6.3.1.3.

To remedy, we just change the comparison from `<` to `<=` so that
yi == x situation can properly be handled.

diff --git a/bignum.c b/bignum.c
index 6edb7f0..5d14306 100644
--- a/bignum.c
+++ b/bignum.c
@@ -5369,6 +5369,15 @@ rb_integer_float_cmp(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/bignum.c#L5369
     return INT2FIX(-1);
 }
 
+COMPILER_WARNING_PUSH
+#ifdef __has_warning
+#if __has_warning("-Wimplicit-int-float-conversion")
+COMPILER_WARNING_IGNORED(-Wimplicit-int-float-conversion)
+#endif
+#endif
+static const double LONG_MAX_as_double = LONG_MAX;
+COMPILER_WARNING_POP
+
 VALUE
 rb_integer_float_eq(VALUE x, VALUE y)
 {
@@ -5388,7 +5397,7 @@ rb_integer_float_eq(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/bignum.c#L5397
         return Qtrue;
 #else
         long xn, yn;
-        if (yi < LONG_MIN || LONG_MAX < yi)
+        if (yi < LONG_MIN || LONG_MAX_as_double <= yi)
             return Qfalse;
         xn = FIX2LONG(x);
         yn = (long)yi;
@@ -5401,6 +5410,7 @@ rb_integer_float_eq(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/bignum.c#L5410
     return rb_big_eq(x, y);
 }
 
+
 VALUE
 rb_big_cmp(VALUE x, VALUE y)
 {
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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