This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Obvious fix for PR66828: left shift with undefined behavior in bswap pass


The bswap pass contain the following loop:

for (i = 0; i < size; i++, inc <<= BITS_PER_MARKER)

In the update to inc and i just before exiting the loop, inc can be shifted by a total of more than 62bit, making the value too large to be represented by int64_t. This is an undefined behavior [1] and it triggers an error under an ubsan bootstrap. This patch change the type of inc to be unsigned, removing the undefined behavior.

[1] C++ 98 standard section 5.8 paragraph 2:

"The value of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are zero-filled. If E1 has an unsigned type, the value of the result is E1 Ã 2E2 , reduced modulo one more than the maximum value representable in the result type. Otherwise, if E1 has a signed type and non-negative value, and E1 Ã 2E2 is representable in the corresponding unsigned type of the result type, then that value, converted to the result type, is the resulting value; otherwise, the
behavior is undefined."

ChangeLog entry is as follows:

2015-07-28  Thomas Preud'homme  <thomas.preudhomme@arm.com>

        PR tree-optimization/66828
        * tree-ssa-math-opts.c (perform_symbolic_merge): Change type of inc
        from int64_t to uint64_t.

Testsuite was run on a native x86_64-linux-gnu bootstrapped GCC and an arm-none-eabi cross-compiler without any regression. Committed as obvious as suggested by  Markus Trippelsdorf in PR66828.

Best regards,

Thomas



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]