[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=