From b1183c1ff3b17689c036d5e7443b7343074d2f6f Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Mon, 6 Aug 2007 20:52:17 +0000 Subject: [PATCH] This fixes resizing issues with BitVectors. It ensures that the BitWord type and type size is always used, and ensures completely correct clearing of unused high bits, and setting of bits when resizing. It should resolve PR1563. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@40871 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/BitVector.h | 37 +++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h index 243a8102cf8..50ccdab159e 100644 --- a/include/llvm/ADT/BitVector.h +++ b/include/llvm/ADT/BitVector.h @@ -186,13 +186,17 @@ public: init_words(&Bits[OldCapacity], (Capacity-OldCapacity), t); } - // If we previously had no size, initialize the low word - if (Size == 0) - for (unsigned i = 0; i < Capacity; ++i) - Bits[i] = 0 - (unsigned)t; + // Set any old unused bits that are now included in the BitVector. This + // may set bits that are not included in the new vector, but we will clear + // them back out below. + if (N > Size) + set_unused_bits(t); + // Update the size, and clear out any bits that are now unused + unsigned OldSize = Size; Size = N; - clear_unused_bits(); + if (t || N < OldSize) + clear_unused_bits(); } void reserve(unsigned N) { @@ -303,7 +307,7 @@ public: } // Grow the bitvector to have enough elements. - Capacity = NumBitWords(Size); + Capacity = RHSWords; BitWord *NewBits = new BitWord[Capacity]; std::copy(RHS.Bits, &RHS.Bits[RHSWords], NewBits); @@ -318,16 +322,27 @@ private: unsigned NumBitWords(unsigned S) const { return (S + BITWORD_SIZE-1) / BITWORD_SIZE; } - - // Clear the unused top bits in the high word. - void clear_unused_bits() { + + // Set the unused bits in the high words. + void set_unused_bits(bool t = true) { + // Set high words first. + unsigned UsedWords = NumBitWords(Size); + if (Capacity > UsedWords) + init_words(&Bits[UsedWords], (Capacity-UsedWords), t); + + // Then set any stray high bits of the last used word. unsigned ExtraBits = Size % BITWORD_SIZE; if (ExtraBits) { - unsigned index = Size / BITWORD_SIZE; - Bits[index] &= ~(~0L << ExtraBits); + Bits[UsedWords-1] &= ~(~0L << ExtraBits); + Bits[UsedWords-1] |= (0 - (BitWord)t) << ExtraBits; } } + // Clear the unused bits in the high words. + void clear_unused_bits() { + set_unused_bits(false); + } + void grow(unsigned NewSize) { unsigned OldCapacity = Capacity; Capacity = NumBitWords(NewSize);