#include "llvm/ParameterAttributes.h"
#include "llvm/DerivedTypes.h"
#include "llvm/InlineAsm.h"
-#include "llvm/Instructions.h"
-#include "llvm/Intrinsics.h"
+#include "llvm/IntrinsicInst.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/CodeGen/ValueTypes.h"
}
void Verifier::visitGlobalVariable(GlobalVariable &GV) {
- if (GV.hasInitializer())
+ if (GV.hasInitializer()) {
Assert1(GV.getInitializer()->getType() == GV.getType()->getElementType(),
"Global variable initializer type does not match global "
"variable type!", &GV);
+ } else {
+ Assert1(GV.hasExternalLinkage() || GV.hasDLLImportLinkage() ||
+ GV.hasExternalWeakLinkage(),
+ "invalid linkage type for global declaration", &GV);
+ }
visitGlobalValue(GV);
}
void Verifier::visitFunction(Function &F) {
// Check function arguments.
const FunctionType *FT = F.getFunctionType();
- unsigned NumArgs = F.getArgumentList().size();
+ unsigned NumArgs = F.arg_size();
Assert2(FT->getNumParams() == NumArgs,
"# formal arguments must match # of arguments for function type!",
ParamAttr::ByVal | ParamAttr::InReg |
ParamAttr::Nest | ParamAttr::StructRet;
+ const uint16_t MutuallyIncompatible2 =
+ ParamAttr::ZExt | ParamAttr::SExt;
+
const uint16_t IntegerTypeOnly =
ParamAttr::SExt | ParamAttr::ZExt;
uint16_t RetI = Attrs->getParamAttrs(0) & ReturnIncompatible;
Assert1(!RetI, "Attribute " + Attrs->getParamAttrsText(RetI) +
"should not apply to functions!", &F);
+ uint16_t MutI = Attrs->getParamAttrs(0) & MutuallyIncompatible2;
+ Assert1(MutI != MutuallyIncompatible2, "Attributes" +
+ Attrs->getParamAttrsText(MutI) + "are incompatible!", &F);
for (FunctionType::param_iterator I = FT->param_begin(),
E = FT->param_end(); I != E; ++I, ++Idx) {
Assert1(!(MutI & (MutI - 1)), "Attributes " +
Attrs->getParamAttrsText(MutI) + "are incompatible!", &F);
+ uint16_t MutI2 = Attr & MutuallyIncompatible2;
+ Assert1(MutI2 != MutuallyIncompatible2, "Attributes" +
+ Attrs->getParamAttrsText(MutI2) + "are incompatible!", &F);
+
uint16_t IType = Attr & IntegerTypeOnly;
Assert1(!IType || FT->getParamType(Idx-1)->isInteger(),
"Attribute " + Attrs->getParamAttrsText(IType) +
"Functions cannot take aggregates as arguments by value!", I);
}
- if (!F.isDeclaration()) {
+ if (F.isDeclaration()) {
+ Assert1(F.hasExternalLinkage() || F.hasDLLImportLinkage() ||
+ F.hasExternalWeakLinkage(),
+ "invalid linkage type for function declaration", &F);
+ } else {
// Verify that this function (which has a body) is not named "llvm.*". It
// is not legal to define intrinsics.
if (F.getName().size() >= 5)
SmallVector<Value*, 16> Idxs(GEP.idx_begin(), GEP.idx_end());
const Type *ElTy =
GetElementPtrInst::getIndexedType(GEP.getOperand(0)->getType(),
- &Idxs[0], Idxs.size(), true);
+ Idxs.begin(), Idxs.end(), true);
Assert1(ElTy, "Invalid indices for GEP pointer type!", &GEP);
Assert2(isa<PointerType>(GEP.getType()) &&
cast<PointerType>(GEP.getType())->getElementType() == ElTy,
InstsInThisBlock.insert(&I);
}
+static bool HasPtrPtrType(Value *Val) {
+ if (const PointerType *PtrTy = dyn_cast<PointerType>(Val->getType()))
+ return isa<PointerType>(PtrTy->getElementType());
+ return false;
+}
+
/// visitIntrinsicFunction - Allow intrinsics to be verified in different ways.
///
void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
#define GET_INTRINSIC_VERIFIER
#include "llvm/Intrinsics.gen"
#undef GET_INTRINSIC_VERIFIER
+
+ switch (ID) {
+ default:
+ break;
+ case Intrinsic::gcroot:
+ Assert1(HasPtrPtrType(CI.getOperand(1)),
+ "llvm.gcroot parameter #1 must be a pointer to a pointer.", &CI);
+ Assert1(isa<AllocaInst>(IntrinsicInst::StripPointerCasts(CI.getOperand(1))),
+ "llvm.gcroot parameter #1 must be an alloca (or a bitcast of one).",
+ &CI);
+ Assert1(isa<Constant>(CI.getOperand(2)),
+ "llvm.gcroot parameter #2 must be a constant.", &CI);
+ break;
+ case Intrinsic::gcwrite:
+ Assert1(CI.getOperand(3)->getType()
+ == PointerType::get(CI.getOperand(1)->getType()),
+ "Call to llvm.gcwrite must be with type 'void (%ty*, %ty2*, %ty**)'.",
+ &CI);
+ break;
+ case Intrinsic::gcread:
+ Assert1(CI.getOperand(2)->getType() == PointerType::get(CI.getType()),
+ "Call to llvm.gcread must be with type '%ty* (%ty2*, %ty**).'",
+ &CI);
+ break;
+ }
}
/// VerifyIntrinsicPrototype - TableGen emits calls to this function into
}
}
} else if (VT == MVT::iAny) {
+ if (!EltTy->isInteger()) {
+ if (ArgNo == 0)
+ CheckFailed("Intrinsic result type is not "
+ "an integer type.", F);
+ else
+ CheckFailed("Intrinsic parameter #" + utostr(ArgNo-1) + " is not "
+ "an integer type.", F);
+ break;
+ }
unsigned GotBits = cast<IntegerType>(EltTy)->getBitWidth();
Suffix += ".";
if (EltTy != Ty)
CheckFailed("Intrinsic requires even byte width argument", F);
break;
}
+ } else if (VT == MVT::fAny) {
+ if (!EltTy->isFloatingPoint()) {
+ if (ArgNo == 0)
+ CheckFailed("Intrinsic result type is not "
+ "a floating-point type.", F);
+ else
+ CheckFailed("Intrinsic parameter #" + utostr(ArgNo-1) + " is not "
+ "a floating-point type.", F);
+ break;
+ }
+ Suffix += ".";
+ if (EltTy != Ty)
+ Suffix += "v" + utostr(NumElts);
+ Suffix += MVT::getValueTypeString(MVT::getValueType(EltTy));
} else if (VT == MVT::iPTR) {
if (!isa<PointerType>(Ty)) {
- CheckFailed("Intrinsic parameter #" + utostr(ArgNo-1) + " is not a "
- "pointer and a pointer is required.", F);
+ if (ArgNo == 0)
+ CheckFailed("Intrinsic result type is not a "
+ "pointer and a pointer is required.", F);
+ else
+ CheckFailed("Intrinsic parameter #" + utostr(ArgNo-1) + " is not a "
+ "pointer and a pointer is required.", F);
break;
}
} else if (MVT::isVector(VT)) {