From: David Blaikie Date: Fri, 17 Apr 2015 06:40:14 +0000 (+0000) Subject: [opaque pointer type] Explicit pointee type for call instruction X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=5023f151a7501d68d7c0f2bf94f0fb6badb93ae8 [opaque pointer type] Explicit pointee type for call instruction Use an extra bit in the CCInfo to flag the newer version of the instructiont hat includes the type explicitly. Tested the newer error cases I added, but didn't add tests for the finer granularity improvements to existing error paths. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235160 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 5366f5fb4ea..e37e8f49b33 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/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(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(Callee->getType()); - FunctionType *FTy = nullptr; - if (OpTy) FTy = dyn_cast(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(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 Args; // Read the fixed params. diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index aa4a6a4c28a..bfcaac11257 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/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(I); - PointerType *PTy = cast(CI.getCalledValue()->getType()); - FunctionType *FTy = cast(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/test/Bitcode/Inputs/invalid-call-mismatched-explicit-type.bc b/test/Bitcode/Inputs/invalid-call-mismatched-explicit-type.bc new file mode 100644 index 00000000000..802d28edbf4 Binary files /dev/null and b/test/Bitcode/Inputs/invalid-call-mismatched-explicit-type.bc differ diff --git a/test/Bitcode/Inputs/invalid-call-non-function-explicit-type.bc b/test/Bitcode/Inputs/invalid-call-non-function-explicit-type.bc new file mode 100644 index 00000000000..d080689e567 Binary files /dev/null and b/test/Bitcode/Inputs/invalid-call-non-function-explicit-type.bc differ diff --git a/test/Bitcode/invalid.test b/test/Bitcode/invalid.test index 9cab227ab19..5c6e280024c 100644 --- a/test/Bitcode/invalid.test +++ b/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