ensure that every error return sets a message (and goes through Error, for
authorChris Lattner <sabre@nondot.org>
Tue, 24 Apr 2007 18:15:21 +0000 (18:15 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 24 Apr 2007 18:15:21 +0000 (18:15 +0000)
easy breakpointing).

Fix bugs reading constantexpr geps.  We now can disassemble kc++ global
initializers.

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

lib/Bitcode/Reader/BitcodeReader.cpp
lib/Bitcode/Reader/BitcodeReader.h
lib/Bitcode/Reader/ReaderWrappers.cpp

index 87f0369c2ac0dd67ecfd638a1c32511f9c966db3..6f824c63b889856d350b2ae8bc007ecd6f5d01a6 100644 (file)
@@ -161,7 +161,9 @@ bool BitcodeReader::ParseTypeTable(BitstreamReader &Stream) {
     if (Code == bitc::END_BLOCK) {
       if (NumRecords != TypeList.size())
         return Error("Invalid type forward reference in TYPE_BLOCK");
-      return Stream.ReadBlockEnd();
+      if (Stream.ReadBlockEnd())
+        return Error("Error at end of type table block");
+      return false;
     }
     
     if (Code == bitc::ENTER_SUBBLOCK) {
@@ -299,8 +301,11 @@ bool BitcodeReader::ParseTypeSymbolTable(BitstreamReader &Stream) {
   std::string TypeName;
   while (1) {
     unsigned Code = Stream.ReadCode();
-    if (Code == bitc::END_BLOCK)
-      return Stream.ReadBlockEnd();
+    if (Code == bitc::END_BLOCK) {
+      if (Stream.ReadBlockEnd())
+        return Error("Error at end of type symbol table block");
+      return false;
+    }
     
     if (Code == bitc::ENTER_SUBBLOCK) {
       // No known subblocks, always skip them.
@@ -344,9 +349,11 @@ bool BitcodeReader::ParseValueSymbolTable(BitstreamReader &Stream) {
   SmallString<128> ValueName;
   while (1) {
     unsigned Code = Stream.ReadCode();
-    if (Code == bitc::END_BLOCK)
-      return Stream.ReadBlockEnd();
-    
+    if (Code == bitc::END_BLOCK) {
+      if (Stream.ReadBlockEnd())
+        return Error("Error at end of value symbol table block");
+      return false;
+    }    
     if (Code == bitc::ENTER_SUBBLOCK) {
       // No known subblocks, always skip them.
       Stream.ReadSubBlockID();
@@ -420,7 +427,9 @@ bool BitcodeReader::ParseConstants(BitstreamReader &Stream) {
       if (NextCstNo != ValueList.size())
         return Error("Invalid constant reference!");
       
-      return Stream.ReadBlockEnd();
+      if (Stream.ReadBlockEnd())
+        return Error("Error at end of constants block");
+      return false;
     }
     
     if (Code == bitc::ENTER_SUBBLOCK) {
@@ -515,21 +524,25 @@ bool BitcodeReader::ParseConstants(BitstreamReader &Stream) {
     case bitc::CST_CODE_CE_BINOP: {  // CE_BINOP: [opcode, opval, opval]
       if (Record.size() < 3) return Error("Invalid CE_BINOP record");
       int Opc = GetDecodedBinaryOpcode(Record[0], CurTy);
-      if (Opc < 0) return UndefValue::get(CurTy);  // Unknown binop.
-      
-      Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy);
-      Constant *RHS = ValueList.getConstantFwdRef(Record[2], CurTy);
-      V = ConstantExpr::get(Opc, LHS, RHS);
+      if (Opc < 0) {
+        V = UndefValue::get(CurTy);  // Unknown binop.
+      } else {
+        Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy);
+        Constant *RHS = ValueList.getConstantFwdRef(Record[2], CurTy);
+        V = ConstantExpr::get(Opc, LHS, RHS);
+      }
       break;
     }  
     case bitc::CST_CODE_CE_CAST: {  // CE_CAST: [opcode, opty, opval]
       if (Record.size() < 3) return Error("Invalid CE_CAST record");
       int Opc = GetDecodedCastOpcode(Record[0]);
-      if (Opc < 0) return UndefValue::get(CurTy);  // Unknown cast.
-      
-      const Type *OpTy = getTypeByID(Record[1]);
-      Constant *Op = ValueList.getConstantFwdRef(Record[2], OpTy);
-      V = ConstantExpr::getCast(Opc, Op, CurTy);
+      if (Opc < 0) {
+        V = UndefValue::get(CurTy);  // Unknown cast.
+      } else {
+        const Type *OpTy = getTypeByID(Record[1]);
+        Constant *Op = ValueList.getConstantFwdRef(Record[2], OpTy);
+        V = ConstantExpr::getCast(Opc, Op, CurTy);
+      }
       break;
     }  
     case bitc::CST_CODE_CE_GEP: {  // CE_GEP:        [n x operands]
@@ -540,7 +553,8 @@ bool BitcodeReader::ParseConstants(BitstreamReader &Stream) {
         if (!ElTy) return Error("Invalid CE_GEP record");
         Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], ElTy));
       }
-      return ConstantExpr::getGetElementPtr(Elts[0], &Elts[1], Elts.size()-1);
+      V = ConstantExpr::getGetElementPtr(Elts[0], &Elts[1], Elts.size()-1);
+      break;
     }
     case bitc::CST_CODE_CE_SELECT:  // CE_SELECT: [opval#, opval#, opval#]
       if (Record.size() < 3) return Error("Invalid CE_SELECT record");
@@ -634,7 +648,9 @@ bool BitcodeReader::ParseModule(BitstreamReader &Stream,
     if (Code == bitc::END_BLOCK) {
       if (!GlobalInits.empty())
         return Error("Malformed global initializer set");
-      return Stream.ReadBlockEnd();
+      if (Stream.ReadBlockEnd())
+        return Error("Error at end of module block");
+      return false;
     }
     
     if (Code == bitc::ENTER_SUBBLOCK) {
index c7c61529ffcece64e8eab188307ce05210ce048e..3935ebbfe099855d6547c7f0d39aabbc6a425415 100644 (file)
@@ -58,6 +58,7 @@ class BitcodeReader : public ModuleProvider {
   BitcodeReaderValueList ValueList;
   std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
 public:
+  BitcodeReader() : ErrorString(0) {}
   virtual ~BitcodeReader() {}
   
   virtual void FreeState() {}
index 7f6a80953a7d95db6492baa7f9ac6666b5ed5a8a..8bf81a2f838ba88daf1b11d6e2116e37fca490de 100644 (file)
@@ -51,6 +51,7 @@ bool BitcodeFileReader::Read(std::string *ErrMsg) {
   unsigned char *Buffer = reinterpret_cast<unsigned char*>(File.base());
   if (!ParseBitcode(Buffer, File.size(), Filename))
     return false;
+  assert(getErrorString() && "Didn't set an error string?");
   if (ErrMsg) *ErrMsg = getErrorString();
   return true;
 }