ruby-changes:53521
From: shyouhei <ko1@a...>
Date: Thu, 15 Nov 2018 15:17:58 +0900 (JST)
Subject: [ruby-changes:53521] shyouhei:r65737 (trunk): hash.c: cast from double to unsigned is undefined
shyouhei 2018-11-15 15:17:53 +0900 (Thu, 15 Nov 2018) New Revision: 65737 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=65737 Log: hash.c: cast from double to unsigned is undefined When a negative double is casted into an unsigned type, that operation is undefined (cf: ISO/IEC 9899:1990 section 6.2.9.3). Recent versions of C kindly footnotes that "The remaindering operation performed when a value of integer type is converted to unsigned type need not be performed when a value of real floating type is converted to unsigned type" (cf: ISO/IEC 9899:1999 section 6.3.1.4 footnote 50). So it is a wrong idea to just cast a double to st_data_t. The intention of the code is commented as "mix the actual float value in". It seems we should do a reinterpret_cast and rule out static_cast. Confirmed this changeset does not affect `make benchmark`. Modified files: trunk/hash.c Index: hash.c =================================================================== --- hash.c (revision 65736) +++ hash.c (revision 65737) @@ -293,7 +293,9 @@ rb_ident_hash(st_data_t n) https://github.com/ruby/ruby/blob/trunk/hash.c#L293 * many integers get interpreted as 2.0 or -2.0 [Bug #10761] */ if (FLONUM_P(n)) { - n ^= (st_data_t)rb_float_value(n); + union { double d; st_data_t i; } u; + u.d = rb_float_value(n); + n ^= u.i; } #endif -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/