// 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));
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.
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.
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
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