diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h index 41e50e1690d..c45f5fcc200 100644 --- a/include/llvm/Bitcode/BitstreamReader.h +++ b/include/llvm/Bitcode/BitstreamReader.h @@ -177,11 +177,11 @@ class BitstreamCursor { /// follow the word size of the host machine for efficiency. We use word_t in /// places that are aware of this to make it perfectly explicit what is going /// on. - typedef uint32_t word_t; + typedef size_t word_t; word_t CurWord; /// This is the number of bits in CurWord that are valid. This is always from - /// [0...31/63] inclusive (depending on word size). + /// [0...bits_of(size_t)-1] inclusive. unsigned BitsInCurWord; // This is the declared size of code values used for the current block, in @@ -333,7 +333,6 @@ public: Size = NextChar; return; } - assert(BytesRead == sizeof(Array)); // Handle big-endian byte-swapping if necessary. support::detail::packed_endian_specific_integral< @@ -341,20 +340,22 @@ public: memcpy(&EndianValue, Array, sizeof(Array)); CurWord = EndianValue; - NextChar += sizeof(word_t); - BitsInCurWord = sizeof(word_t) * 8; + NextChar += BytesRead; + BitsInCurWord = BytesRead * 8; } uint32_t Read(unsigned NumBits) { assert(NumBits && NumBits <= 32 && "Cannot return zero or more than 32 bits!"); + static const unsigned Mask = sizeof(word_t) > 4 ? 0x3f : 0x1f; + // If the field is fully contained by CurWord, return it quickly. if (BitsInCurWord >= NumBits) { uint32_t R = uint32_t(CurWord) & (~0U >> (32-NumBits)); // Use a mask to avoid undefined behavior. - CurWord >>= (NumBits & 0x1f); + CurWord >>= (NumBits & Mask); BitsInCurWord -= NumBits; return R; @@ -369,10 +370,11 @@ public: if (BitsLeft > BitsInCurWord) return 0; - uint32_t R2 = uint32_t(CurWord) & (~0U >> (sizeof(word_t) * 8 - BitsLeft)); + uint32_t R2 = + uint32_t(CurWord) & (~word_t(0) >> (sizeof(word_t) * 8 - BitsLeft)); // Use a mask to avoid undefined behavior. - CurWord >>= (BitsLeft & 0x1f); + CurWord >>= (BitsLeft & Mask); BitsInCurWord -= BitsLeft; diff --git a/include/llvm/Support/StreamingMemoryObject.h b/include/llvm/Support/StreamingMemoryObject.h index 9325a029e18..6957c6e41ac 100644 --- a/include/llvm/Support/StreamingMemoryObject.h +++ b/include/llvm/Support/StreamingMemoryObject.h @@ -71,14 +71,10 @@ private: size_t bytes = Streamer->GetBytes(&Bytes[BytesRead + BytesSkipped], kChunkSize); BytesRead += bytes; - if (bytes < kChunkSize) { - assert((!ObjectSize || BytesRead >= Pos) && - "Unexpected short read fetching bitcode"); - if (BytesRead <= Pos) { // reached EOF/ran out of bytes - ObjectSize = BytesRead; - EOFReached = true; - return false; - } + if (BytesRead <= Pos) { // reached EOF/ran out of bytes + ObjectSize = BytesRead; + EOFReached = true; + return false; } } return true; diff --git a/lib/Support/StreamingMemoryObject.cpp b/lib/Support/StreamingMemoryObject.cpp index b3723d03981..f0eb83153e0 100644 --- a/lib/Support/StreamingMemoryObject.cpp +++ b/lib/Support/StreamingMemoryObject.cpp @@ -90,13 +90,12 @@ uint64_t StreamingMemoryObject::getExtent() const { uint64_t StreamingMemoryObject::readBytes(uint8_t *Buf, uint64_t Size, uint64_t Address) const { fetchToPos(Address + Size - 1); - uint64_t BufferSize = Bytes.size() - BytesSkipped; - if (Address >= BufferSize) + if (Address >= BytesRead) return 0; uint64_t End = Address + Size; - if (End > BufferSize) - End = BufferSize; + if (End > BytesRead) + End = BytesRead; Size = End - Address; assert(Size >= 0); memcpy(Buf, &Bytes[Address + BytesSkipped], Size);