Correct a bug introduced by Stéphane in the previous patch.
authorStéphane Nicolet <cassio@free.fr>
Wed, 2 May 2018 11:20:47 +0000 (13:20 +0200)
committerStéphane Nicolet <cassio@free.fr>
Wed, 2 May 2018 11:38:00 +0000 (13:38 +0200)
When we are using the "Bitboard + Square" overloaded operators,
the compiler uses the interpediate SquareBB[s] to transform the
square into a Bitboard, and then calculate the result.

For instance, the following code:

```
   b = pos.pieces(Us, PAWN) & s
```

generates in fact the code:

```
   b = pos.pieces(Us, PAWN) & SquareBB[s]`
```

The bug introduced by Stéphane in the previous patch was the
use of `b = pos.pieces(Us, PAWN) & (s + Up)` which can result
in out-of-bounds errors for the SquareBB[] array if s in the
last rank of the board.

We coorect the bug, and also add some asserts in bitboard.h to
make the code more robust for this particular bug in the future.

Bug report by Joost VandeVondele. Thanks!

Bench: 5512000

src/bitboard.h
src/pawns.cpp

index a813ea1..7ae1eff 100644 (file)
@@ -107,22 +107,27 @@ extern Magic BishopMagics[SQUARE_NB];
 /// whether a given bit is set in a bitboard, and for setting and clearing bits.
 
 inline Bitboard operator&(Bitboard b, Square s) {
+  assert(s >= SQ_A1 && s <= SQ_H8);
   return b & SquareBB[s];
 }
 
 inline Bitboard operator|(Bitboard b, Square s) {
+  assert(s >= SQ_A1 && s <= SQ_H8);
   return b | SquareBB[s];
 }
 
 inline Bitboard operator^(Bitboard b, Square s) {
+  assert(s >= SQ_A1 && s <= SQ_H8);
   return b ^ SquareBB[s];
 }
 
 inline Bitboard& operator|=(Bitboard& b, Square s) {
+  assert(s >= SQ_A1 && s <= SQ_H8);
   return b |= SquareBB[s];
 }
 
 inline Bitboard& operator^=(Bitboard& b, Square s) {
+  assert(s >= SQ_A1 && s <= SQ_H8);
   return b ^= SquareBB[s];
 }
 
index 6664742..3e92600 100644 (file)
@@ -226,8 +226,8 @@ Value Entry::evaluate_shelter(const Position& pos, Square ksq) {
 
   enum { Unopposed, BlockedByPawn, Unblocked };
   constexpr Color     Them = (Us == WHITE ? BLACK : WHITE);
-  constexpr Direction Up   = (Us == WHITE ? NORTH : SOUTH);
-  constexpr Bitboard  BlockRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
+  constexpr Direction Down = (Us == WHITE ? SOUTH : NORTH);
+  constexpr Bitboard  BlockRanks = (Us == WHITE ? Rank1BB | Rank2BB : Rank8BB | Rank7BB);
 
   Bitboard b = pos.pieces(PAWN) & (forward_ranks_bb(Us, ksq) | rank_bb(ksq));
   Bitboard ourPawns = b & pos.pieces(Us);
@@ -235,7 +235,7 @@ Value Entry::evaluate_shelter(const Position& pos, Square ksq) {
 
   Value safety = (ourPawns & file_bb(ksq)) ? Value(5) : Value(-5);
 
-  if ((theirPawns & (FileABB | FileHBB) & BlockRanks) & (ksq + Up))
+  if ((shift<Down>(theirPawns) & (FileABB | FileHBB) & BlockRanks) & ksq)
       safety += 374;
 
   File center = std::max(FILE_B, std::min(FILE_G, file_of(ksq)));