diff --git a/m-bitset.h b/m-bitset.h index 3d9a1827..f077ebac 100644 --- a/m-bitset.h +++ b/m-bitset.h @@ -268,8 +268,8 @@ m_bitset_resize (m_bitset_t v, size_t size) } } else if (size > old_size) { // Resize up the bitset: set to 0 new bits. - const size_t old_offset = old_size / M_B1TSET_LIMB_BIT; - for(size_t i = old_offset+1 ; i < offset; i++) { + const size_t old_offset = (old_size + M_B1TSET_LIMB_BIT - 1)/ M_B1TSET_LIMB_BIT; + for(size_t i = old_offset ; i < offset; i++) { v->ptr[i] = 0; } if (M_LIKELY(index != 0)) { diff --git a/tests/test-mbitset.c b/tests/test-mbitset.c index 3570b575..52f1f964 100644 --- a/tests/test-mbitset.c +++ b/tests/test-mbitset.c @@ -420,6 +420,29 @@ static void test_clz(void) } } +// Detect bug on bitset_resize function in case of increase of size. +// the first limb may not be cleared properly in some cases +static void test_resize(void) +{ + M_LET(set, bitset_t) { + for(size_t i = 1; i < 257; i++) { + bitset_resize(set, i); + assert( bitset_get(set, i-1) == false); + bitset_set_at(set, 0, true); + bitset_set_at(set, i-1, true); + bitset_reset(set); + bitset_resize(set, i); + assert( bitset_get(set, 0) == false); + assert( bitset_get(set, i-1) == false); + bitset_set_at(set, 0, true); + bitset_set_at(set, i-1, true); + bitset_resize(set, i-1); + bitset_resize(set, i); + assert( bitset_get(set, i-1) == false); + } + } +} + int main(void) { test1(); @@ -428,5 +451,6 @@ int main(void) test_logic(); test_let(); test_clz(); + test_resize(); exit(0); }