Fix the underlying problem that was causing read(0) to be called: sometimes the
authorChris Lattner <sabre@nondot.org>
Sat, 9 Feb 2013 07:07:29 +0000 (07:07 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 9 Feb 2013 07:07:29 +0000 (07:07 +0000)
bitcode writer would generate abbrev records saying that the abbrev should be
filled with fixed zero-bit bitfields (this happens in the .bc writer when
the number of types used in a module is exactly one, since log2(1) == 0).

In this case, just handle it as a literal zero.  We can't "just fix" the writer
without breaking compatibility with existing bc files, so have the abbrev reader
do the substitution.

Strengthen the assert in read to reject reads of zero bits so we catch such
crimes in the future, and remove the special case designed to handle this.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174801 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Bitcode/BitstreamReader.h
lib/Bitcode/Reader/BitstreamReader.cpp

index 1b29c3e639ab8b3776913b8115c8bcb954379bb9..56a610883bcab133fe508413450b6c65720b3a21 100644 (file)
@@ -343,8 +343,8 @@ public:
 
 
   uint32_t Read(unsigned NumBits) {
-    assert(NumBits <= 32 && "Cannot return more than 32 bits!");
-    if (NumBits == 0) return 0;
+    assert(NumBits && NumBits <= 32 &&
+           "Cannot return zero or more than 32 bits!");
     
     // If the field is fully contained by CurWord, return it quickly.
     if (BitsInCurWord >= NumBits) {
index 85076f35020d6a694929e303bec95b4cb9dc6fca..b1335029a7587e8baaee518ce6dfd182f905a56f 100644 (file)
@@ -288,9 +288,20 @@ void BitstreamCursor::ReadAbbrevRecord() {
     }
 
     BitCodeAbbrevOp::Encoding E = (BitCodeAbbrevOp::Encoding)Read(3);
-    if (BitCodeAbbrevOp::hasEncodingData(E))
-      Abbv->Add(BitCodeAbbrevOp(E, ReadVBR64(5)));
-    else
+    if (BitCodeAbbrevOp::hasEncodingData(E)) {
+      unsigned Data = ReadVBR64(5);
+
+      // As a special case, handle fixed(0) (i.e., a fixed field with zero bits)
+      // and vbr(0) as a literal zero.  This is decoded the same way, and avoids
+      // a slow path in Read() to have to handle reading zero bits.
+      if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) &&
+          Data == 0) {
+        Abbv->Add(BitCodeAbbrevOp(0));
+        continue;
+      }
+      
+      Abbv->Add(BitCodeAbbrevOp(E, Data));
+    } else
       Abbv->Add(BitCodeAbbrevOp(E));
   }
   CurAbbrevs.push_back(Abbv);