1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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.
This commit is contained in:
卜部昌平 2019-09-05 14:29:11 +09:00
parent dd2b9d4a96
commit 41bc766763

View file

@ -5369,6 +5369,15 @@ rb_integer_float_cmp(VALUE x, VALUE y)
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)
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)
return rb_big_eq(x, y);
}
VALUE
rb_big_cmp(VALUE x, VALUE y)
{