summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Bitcode
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Bitcode')
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp31
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp6
2 files changed, 25 insertions, 12 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 5366f5fb4ea..e37e8f49b33 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -299,9 +299,9 @@ private:
// have.
ResVal = getFnValueByID(ValNo, nullptr);
return ResVal == nullptr;
- } else if (Slot == Record.size()) {
- return true;
}
+ if (Slot == Record.size())
+ return true;
unsigned TypeNo = (unsigned)Record[Slot++];
ResVal = getFnValueByID(ValNo, getTypeByID(TypeNo));
@@ -4168,19 +4168,32 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) {
if (Record.size() < 3)
return Error("Invalid record");
- AttributeSet PAL = getAttributes(Record[0]);
- unsigned CCInfo = Record[1];
+ unsigned OpNum = 0;
+ AttributeSet PAL = getAttributes(Record[OpNum++]);
+ unsigned CCInfo = Record[OpNum++];
+
+ FunctionType *FTy = nullptr;
+ if (CCInfo >> 15 & 1 &&
+ !(FTy = dyn_cast<FunctionType>(getTypeByID(Record[OpNum++]))))
+ return Error("Explicit call type is not a function type");
- unsigned OpNum = 2;
Value *Callee;
if (getValueTypePair(Record, OpNum, NextValueNo, Callee))
return Error("Invalid record");
PointerType *OpTy = dyn_cast<PointerType>(Callee->getType());
- FunctionType *FTy = nullptr;
- if (OpTy) FTy = dyn_cast<FunctionType>(OpTy->getElementType());
- if (!FTy || Record.size() < FTy->getNumParams()+OpNum)
- return Error("Invalid record");
+ if (!OpTy)
+ return Error("Callee is not a pointer type");
+ FunctionType *PFTy = dyn_cast<FunctionType>(OpTy->getElementType());
+ if (!PFTy)
+ return Error("Callee is not of pointer to function type");
+ if (!FTy)
+ FTy = PFTy;
+ if (PFTy != FTy)
+ return Error("Explicit call type does not match pointee type of "
+ "callee operand");
+ if (Record.size() < FTy->getNumParams() + OpNum)
+ return Error("Insufficient operands to call");
SmallVector<Value*, 16> Args;
// Read the fixed params.
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index aa4a6a4c28a..bfcaac11257 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -1935,14 +1935,14 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
break;
case Instruction::Call: {
const CallInst &CI = cast<CallInst>(I);
- PointerType *PTy = cast<PointerType>(CI.getCalledValue()->getType());
- FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
+ FunctionType *FTy = CI.getFunctionType();
Code = bitc::FUNC_CODE_INST_CALL;
Vals.push_back(VE.getAttributeID(CI.getAttributes()));
Vals.push_back((CI.getCallingConv() << 1) | unsigned(CI.isTailCall()) |
- unsigned(CI.isMustTailCall()) << 14);
+ unsigned(CI.isMustTailCall()) << 14 | 1 << 15);
+ Vals.push_back(VE.getTypeID(FTy));
PushValueAndType(CI.getCalledValue(), InstID, Vals, VE); // Callee
// Emit value #'s for the fixed parameters.
OpenPOWER on IntegriCloud