This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Obvious fix for PR66828: left shift with undefined behavior in bswap pass
- From: "Thomas Preud'homme" <thomas dot preudhomme at arm dot com>
- To: <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 28 Jul 2015 14:55:08 +0800
- Subject: [PATCH] Obvious fix for PR66828: left shift with undefined behavior in bswap pass
- Authentication-results: sourceware.org; auth=none
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