[ruby-cvs:79116] 13064fe5db (master): avoid undefined behaviour when n==0
Unknown <[email protected]> Fri, 10 Jan 2020 21:17:26 +0900 (JST)
| Newsgroups | gmane.comp.lang.ruby.cvs |
|---|---|
| Message-ID | <[email protected]> |
=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 2020-01-09 16:50:59 +0900 (Thu, 09 J=
an 2020)
New Revision: 13064fe5db
https://github.com/ruby/ruby/commit/13064fe5db
Log:
avoid undefined behaviour when n=3D=3D0
=
ISO/IEC 9899:1999 section 6.5.7 states that "If the value of the righ=
t
operand is negative or is greater than or equal to the width of the
promoted left operand, the behavior is undefined". So we have to tak=
e
care of such situations.
=
This has not been a problem because contemporary C compilers are
extraordinary smart to compile the series of shifts into a single
ROTLQ/ROTRQ machine instruction. In contrast to what C says those
instructions have fully defined behaviour for all possible inputs.
Hence it has been quite difficult to observe the undefined-ness of su=
ch
situations. But undefined is undefined. We should not rely on such
target-specific assumptions.
=
We are fixing the situation by carefully avoiding shifts with out-of-=
range values. At least GCC since 4.6.3 and Clang since 8.0 can issue=
the exact same instructions like before the changeset.
=
Also in case of Intel processors, there supposedly be intrinsics name=
d
_rotr/_rotl that do exactly what we need. They, in practice, are abs=
ent
on Clang before 9.x so we cannot blindly use. But we can at least sa=
ve
MSVC.
=
See also:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D57157
https://bugs.llvm.org/show_bug.cgi?id=3D17332
Modified files:
configure.ac
internal/bits.h=