diff options
Diffstat (limited to 'llvm/lib/Bitcode')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 31 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 6 |
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. |