[opaque pointer type] Bitcode support for explicit type parameter on the gep operator
authorDavid Blaikie <dblaikie@gmail.com>
Fri, 13 Mar 2015 21:03:36 +0000 (21:03 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Fri, 13 Mar 2015 21:03:36 +0000 (21:03 +0000)
This happened to be fairly easy to support backwards compatibility based
on the number of operands (old format had an even number, new format has
one more operand so an odd number).

test/Bitcode/old-aliases.ll already appears to test old gep operators
(if I remove the backwards compatibility in the BitcodeReader, this and
another test fail) so I'm not adding extra test coverage here.

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

include/llvm/IR/Operator.h
lib/Bitcode/Reader/BitcodeReader.cpp
lib/Bitcode/Writer/BitcodeWriter.cpp

index 46935ce3e9612789e7cb9ab49190513fbdee255c..c87f89c6157ec5b2de7bbf8dc068bc79181a3845 100644 (file)
@@ -400,6 +400,11 @@ public:
     return getPointerOperand()->getType();
   }
 
+  Type *getSourceElementType() const {
+    return cast<SequentialType>(getPointerOperandType()->getScalarType())
+        ->getElementType();
+  }
+
   /// Method to return the address space of the pointer operand.
   unsigned getPointerAddressSpace() const {
     return getPointerOperandType()->getPointerAddressSpace();
index 33b02f912f0cd361f533bfc39c4ced97d31062f2..9a0ec19e6f36326ce50302dc2c7dca35be14162d 100644 (file)
@@ -1955,19 +1955,25 @@ std::error_code BitcodeReader::ParseConstants() {
     }
     case bitc::CST_CODE_CE_INBOUNDS_GEP:
     case bitc::CST_CODE_CE_GEP: {  // CE_GEP:        [n x operands]
-      if (Record.size() & 1)
-        return Error("Invalid record");
+      unsigned OpNum = 0;
+      Type *PointeeType = nullptr;
+      if (Record.size() % 2)
+        PointeeType = getTypeByID(Record[OpNum++]);
       SmallVector<Constant*, 16> Elts;
-      for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
-        Type *ElTy = getTypeByID(Record[i]);
+      while (OpNum != Record.size()) {
+        Type *ElTy = getTypeByID(Record[OpNum++]);
         if (!ElTy)
           return Error("Invalid record");
-        Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], ElTy));
+        Elts.push_back(ValueList.getConstantFwdRef(Record[OpNum++], ElTy));
       }
+
       ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end());
       V = ConstantExpr::getGetElementPtr(Elts[0], Indices,
                                          BitCode ==
                                            bitc::CST_CODE_CE_INBOUNDS_GEP);
+      if (PointeeType &&
+          PointeeType != cast<GEPOperator>(V)->getSourceElementType())
+        return Error("Invalid record");
       break;
     }
     case bitc::CST_CODE_CE_SELECT: {  // CE_SELECT: [opval#, opval#, opval#]
index ecb6f7c130a4827676c3472cd294e364f259b817..d2417acc689b774f5a2b58cb35082db687ab2a1d 100644 (file)
@@ -1522,15 +1522,18 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
             Record.push_back(Flags);
         }
         break;
-      case Instruction::GetElementPtr:
+      case Instruction::GetElementPtr: {
         Code = bitc::CST_CODE_CE_GEP;
-        if (cast<GEPOperator>(C)->isInBounds())
+        const auto *GO = cast<GEPOperator>(C);
+        if (GO->isInBounds())
           Code = bitc::CST_CODE_CE_INBOUNDS_GEP;
+        Record.push_back(VE.getTypeID(GO->getSourceElementType()));
         for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) {
           Record.push_back(VE.getTypeID(C->getOperand(i)->getType()));
           Record.push_back(VE.getValueID(C->getOperand(i)));
         }
         break;
+      }
       case Instruction::Select:
         Code = bitc::CST_CODE_CE_SELECT;
         Record.push_back(VE.getValueID(C->getOperand(0)));