Hi!
I've been working on running PHP with undefined behavior sanitizer
(http://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) and I've
encountered a weird error while running PHP:
/src/php-src/Zend/zend_alloc.c:585:9: runtime error: shift exponent 138
is too large for 64-bit type 'zend_mm_bitset' (aka 'unsigned long')
#0 0x86dada in zend_mm_bitset_is_set
/src/php-src/Zend/zend_alloc.c:585:9
#1 0x86dada in zend_mm_bitset_is_free_range
/src/php-src/Zend/zend_alloc.c:665
#2 0x86dada in zend_mm_realloc_heap /src/php-src/Zend/zend_alloc.c:1670
#3 0x86dada in _erealloc2 /src/php-src/Zend/zend_alloc.c:2577
Looks like the code is doing it intentionally:
/* x86 instructions BT, SHL, SHR don't require masking */
#if defined(GNUC) && (defined(i386) || defined(x86_64)) ||
defined(ZEND_WIN32)
define ZEND_BIT_TEST(bits, bit) (((bits)[(bit) /
(sizeof((bits)[0])*8)] >> (bit)) & 1)
#else
define ZEND_BIT_TEST(bits, bit) (((bits)[(bit) /
(sizeof((bits)[0])*8)] >> ((bit) & (sizeof((bits)[0])*8-1))) & 1)
#endif
But I'm not sure how it's supposed to work. Is it correct that on GCC
(and clang, presumably, since it defines GNUC) accept long bitshifts
and do the right thing with argument like 138? Is it documented
anywhere? Or is there a bug here?
Thanks,
Stas Malyshev
smalyshev@gmail.com