diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 31 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 6 | ||||
-rw-r--r-- | llvm/test/Bitcode/Inputs/invalid-call-mismatched-explicit-type.bc | bin | 0 -> 1316 bytes | |||
-rw-r--r-- | llvm/test/Bitcode/Inputs/invalid-call-non-function-explicit-type.bc | bin | 0 -> 1316 bytes | |||
-rw-r--r-- | llvm/test/Bitcode/invalid.test | 6 |
5 files changed, 31 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. diff --git a/llvm/test/Bitcode/Inputs/invalid-call-mismatched-explicit-type.bc b/llvm/test/Bitcode/Inputs/invalid-call-mismatched-explicit-type.bc Binary files differnew file mode 100644 index 00000000000..802d28edbf4 --- /dev/null +++ b/llvm/test/Bitcode/Inputs/invalid-call-mismatched-explicit-type.bc diff --git a/llvm/test/Bitcode/Inputs/invalid-call-non-function-explicit-type.bc b/llvm/test/Bitcode/Inputs/invalid-call-non-function-explicit-type.bc Binary files differnew file mode 100644 index 00000000000..d080689e567 --- /dev/null +++ b/llvm/test/Bitcode/Inputs/invalid-call-non-function-explicit-type.bc diff --git a/llvm/test/Bitcode/invalid.test b/llvm/test/Bitcode/invalid.test index 9cab227ab19..5c6e280024c 100644 --- a/llvm/test/Bitcode/invalid.test +++ b/llvm/test/Bitcode/invalid.test @@ -18,6 +18,10 @@ RUN: not llvm-dis -disable-output %p/Inputs/invalid-load-mismatched-explicit-typ RUN: FileCheck --check-prefix=MISMATCHED-EXPLICIT-LOAD %s RUN: not llvm-dis -disable-output %p/Inputs/invalid-gep-operator-mismatched-explicit-type.bc 2>&1 | \ RUN: FileCheck --check-prefix=MISMATCHED-EXPLICIT-GEP-OPERATOR %s +RUN: not llvm-dis -disable-output %p/Inputs/invalid-call-mismatched-explicit-type.bc 2>&1 | \ +RUN: FileCheck --check-prefix=MISMATCHED-EXPLICIT-CALL %s +RUN: not llvm-dis -disable-output %p/Inputs/invalid-call-non-function-explicit-type.bc 2>&1 | \ +RUN: FileCheck --check-prefix=NON-FUNCTION-EXPLICIT-CALL %s INVALID-ENCODING: Invalid encoding BAD-ABBREV: Abbreviation starts with an Array or a Blob @@ -29,6 +33,8 @@ BAD-ALIGN: Invalid alignment value MISMATCHED-EXPLICIT-GEP: Explicit gep type does not match pointee type of pointer operand MISMATCHED-EXPLICIT-LOAD: Explicit load type does not match pointee type of pointer operand MISMATCHED-EXPLICIT-GEP-OPERATOR: Explicit gep operator type does not match pointee type of pointer operand +MISMATCHED-EXPLICIT-CALL: Explicit call type does not match pointee type of callee operand +NON-FUNCTION-EXPLICIT-CALL: Explicit call type is not a function type RUN: not llvm-dis -disable-output %p/Inputs/invalid-extractval-array-idx.bc 2>&1 | \ RUN: FileCheck --check-prefix=EXTRACT-ARRAY %s |