1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-04-30 00:33:09 +00:00

Guard against UB in lsb/msb

lsb(b) and msb(b) are undefined when b == 0. This can lead to subtle bugs, where
the resulting code behaves differently on different configurations:
- It can be the home grown software LSB/MSB
- It can be the compiler generated software LSB/MSB (when using compiler
  intrinsics without the right compiler flags to allow compiler to use hardware
  LSB/MSB). Which of course depends on the compiler.
- It can be hardware LSB/MSB generated by the compiler.
- Not to mention that hardware LSB/MSB can return different value on different
  hardware when b == 0.

No functional change

Resolves #610
This commit is contained in:
lucasart 2016-03-29 20:37:42 +08:00 committed by Joona Kiiski
parent db4b0d8b7d
commit f256388e08
2 changed files with 13 additions and 2 deletions

View file

@ -81,11 +81,13 @@ namespace {
/// Software fall-back of lsb() and msb() for CPU lacking hardware support /// Software fall-back of lsb() and msb() for CPU lacking hardware support
Square lsb(Bitboard b) { Square lsb(Bitboard b) {
assert(b);
return BSFTable[bsf_index(b)]; return BSFTable[bsf_index(b)];
} }
Square msb(Bitboard b) { Square msb(Bitboard b) {
assert(b);
unsigned b32; unsigned b32;
int result = 0; int result = 0;

View file

@ -261,18 +261,27 @@ inline Bitboard attacks_bb(Piece pc, Square s, Bitboard occupied) {
#if defined(__GNUC__) #if defined(__GNUC__)
inline Square lsb(Bitboard b) { return Square(__builtin_ctzll(b)); } inline Square lsb(Bitboard b) {
inline Square msb(Bitboard b) { return Square(63 - __builtin_clzll(b)); } assert(b);
return Square(__builtin_ctzll(b));
}
inline Square msb(Bitboard b) {
assert(b);
return Square(63 - __builtin_clzll(b));
}
#elif defined(_WIN64) && defined(_MSC_VER) #elif defined(_WIN64) && defined(_MSC_VER)
inline Square lsb(Bitboard b) { inline Square lsb(Bitboard b) {
assert(b);
unsigned long idx; unsigned long idx;
_BitScanForward64(&idx, b); _BitScanForward64(&idx, b);
return (Square) idx; return (Square) idx;
} }
inline Square msb(Bitboard b) { inline Square msb(Bitboard b) {
assert(b);
unsigned long idx; unsigned long idx;
_BitScanReverse64(&idx, b); _BitScanReverse64(&idx, b);
return (Square) idx; return (Square) idx;