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:
parent
dd2b9d4a96
commit
41bc766763
1 changed files with 11 additions and 1 deletions
12
bignum.c
12
bignum.c
|
@ -5369,6 +5369,15 @@ rb_integer_float_cmp(VALUE x, VALUE y)
|
||||||
return INT2FIX(-1);
|
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
|
VALUE
|
||||||
rb_integer_float_eq(VALUE x, VALUE y)
|
rb_integer_float_eq(VALUE x, VALUE y)
|
||||||
{
|
{
|
||||||
|
@ -5388,7 +5397,7 @@ rb_integer_float_eq(VALUE x, VALUE y)
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
#else
|
#else
|
||||||
long xn, yn;
|
long xn, yn;
|
||||||
if (yi < LONG_MIN || LONG_MAX < yi)
|
if (yi < LONG_MIN || LONG_MAX_as_double <= yi)
|
||||||
return Qfalse;
|
return Qfalse;
|
||||||
xn = FIX2LONG(x);
|
xn = FIX2LONG(x);
|
||||||
yn = (long)yi;
|
yn = (long)yi;
|
||||||
|
@ -5401,6 +5410,7 @@ rb_integer_float_eq(VALUE x, VALUE y)
|
||||||
return rb_big_eq(x, y);
|
return rb_big_eq(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_big_cmp(VALUE x, VALUE y)
|
rb_big_cmp(VALUE x, VALUE y)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue