X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FVerifier.cpp;h=0ce7d4c27ce921395c97491ae6f23f28ad33a560;hb=719de53742167ca3f0e6b2efafb6eac18bd90452;hp=4ac8c0f3a482426c8f920190de8fa79cae1b05ec;hpb=950a4c40b823cd4f09dc71be635229246dfd6cac;p=oota-llvm.git diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 4ac8c0f3a48..0ce7d4c27ce 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -21,7 +21,7 @@ // * The code is in valid SSA form // * It should be illegal to put a label into any other type (like a structure) // or to return one. [except constant arrays!] -// * Only phi nodes can be self referential: 'add int %0, %0 ; :0' is bad +// * Only phi nodes can be self referential: 'add i32 %0, %0 ; :0' is bad // * PHI nodes must have an entry for each predecessor, with no extras. // * PHI nodes must be the first thing in a basic block, all grouped together // * PHI nodes must have at least one entry @@ -92,11 +92,14 @@ namespace { // Anonymous namespace for class return false; } }; +} - char PreVerifier::ID = 0; - RegisterPass PreVer("preverify", "Preliminary module verification"); - const PassInfo *PreVerifyID = PreVer.getPassInfo(); +char PreVerifier::ID = 0; +static RegisterPass +PreVer("preverify", "Preliminary module verification"); +static const PassInfo *const PreVerifyID = &PreVer; +namespace { struct VISIBILITY_HIDDEN Verifier : public FunctionPass, InstVisitor { static char ID; // Pass ID, replacement for typeid @@ -305,11 +308,10 @@ namespace { // Anonymous namespace for class Broken = true; } }; - - char Verifier::ID = 0; - RegisterPass X("verify", "Module Verifier"); } // End anonymous namespace +char Verifier::ID = 0; +static RegisterPass X("verify", "Module Verifier"); // Assert - We know that cond should be true, if not print an error message. #define Assert(C, M) \ @@ -367,9 +369,11 @@ void Verifier::visitGlobalAlias(GlobalAlias &GA) { Assert1(GA.hasExternalLinkage() || GA.hasInternalLinkage() || GA.hasWeakLinkage(), "Alias should have external or external weak linkage!", &GA); + Assert1(GA.getAliasee(), + "Aliasee cannot be NULL!", &GA); Assert1(GA.getType() == GA.getAliasee()->getType(), "Alias and aliasee types should match!", &GA); - + if (!isa(GA.getAliasee())) { const ConstantExpr *CE = dyn_cast(GA.getAliasee()); Assert1(CE && CE->getOpcode() == Instruction::BitCast && @@ -586,22 +590,34 @@ void Verifier::visitTerminatorInst(TerminatorInst &I) { void Verifier::visitReturnInst(ReturnInst &RI) { Function *F = RI.getParent()->getParent(); unsigned N = RI.getNumOperands(); - if (N == 0) - Assert2(F->getReturnType() == Type::VoidTy, + if (F->getReturnType() == Type::VoidTy) + Assert2(N == 0, "Found return instr that returns void in Function of non-void " "return type!", &RI, F->getReturnType()); - else if (const StructType *STy = dyn_cast(F->getReturnType())) { - for (unsigned i = 0; i < N; i++) + else if (N == 1 && F->getReturnType() == RI.getOperand(0)->getType()) { + // Exactly one return value and it matches the return type. Good. + } else if (const StructType *STy = dyn_cast(F->getReturnType())) { + // The return type is a struct; check for multiple return values. + Assert2(STy->getNumElements() == N, + "Incorrect number of return values in ret instruction!", + &RI, F->getReturnType()); + for (unsigned i = 0; i != N; ++i) Assert2(STy->getElementType(i) == RI.getOperand(i)->getType(), "Function return type does not match operand " "type of return inst!", &RI, F->getReturnType()); - } - else if (N == 1) - Assert2(F->getReturnType() == RI.getOperand(0)->getType(), - "Function return type does not match operand " - "type of return inst!", &RI, F->getReturnType()); - else - Assert1(0, "Invalid return type!", &RI); + } else if (const ArrayType *ATy = dyn_cast(F->getReturnType())) { + // The return type is an array; check for multiple return values. + Assert2(ATy->getNumElements() == N, + "Incorrect number of return values in ret instruction!", + &RI, F->getReturnType()); + for (unsigned i = 0; i != N; ++i) + Assert2(ATy->getElementType() == RI.getOperand(i)->getType(), + "Function return type does not match operand " + "type of return inst!", &RI, F->getReturnType()); + } else { + CheckFailed("Function return type does not match operand " + "type of return inst!", &RI, F->getReturnType()); + } // Check to make sure that the return value has necessary properties for // terminators... @@ -1040,7 +1056,7 @@ void Verifier::visitGetElementPtrInst(GetElementPtrInst &GEP) { SmallVector Idxs(GEP.idx_begin(), GEP.idx_end()); const Type *ElTy = GetElementPtrInst::getIndexedType(GEP.getOperand(0)->getType(), - Idxs.begin(), Idxs.end(), true); + Idxs.begin(), Idxs.end()); Assert1(ElTy, "Invalid indices for GEP pointer type!", &GEP); Assert2(isa(GEP.getType()) && cast(GEP.getType())->getElementType() == ElTy, @@ -1075,8 +1091,14 @@ void Verifier::visitAllocationInst(AllocationInst &AI) { } void Verifier::visitGetResultInst(GetResultInst &GRI) { - Assert1(GRI.isValidOperands(GRI.getAggregateValue(), GRI.getIndex()), + Assert1(GetResultInst::isValidOperands(GRI.getAggregateValue(), + GRI.getIndex()), "Invalid GetResultInst operands!", &GRI); + Assert1(isa(GRI.getAggregateValue()) || + isa(GRI.getAggregateValue()) || + isa(GRI.getAggregateValue()), + "GetResultInst operand must be a call/invoke/undef!", &GRI); + visitInstruction(GRI); } @@ -1217,7 +1239,7 @@ void Verifier::visitInstruction(Instruction &I) { } // Definition must dominate use unless use is unreachable! - Assert2(DT->dominates(OpBlock, BB) || + Assert2(DT->dominates(Op, &I) || !DT->dominates(&BB->getParent()->getEntryBlock(), BB), "Instruction does not dominate all uses!", Op, &I); } else { @@ -1264,8 +1286,7 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { "Intrinsic parameter #1 is not i8**.", &CI); Assert1(CI.getOperand(2)->getType() == PtrTy, "Intrinsic parameter #2 is not i8*.", &CI); - Assert1(isa( - IntrinsicInst::StripPointerCasts(CI.getOperand(1))), + Assert1(isa(CI.getOperand(1)->stripPointerCasts()), "llvm.gcroot parameter #1 must be an alloca.", &CI); Assert1(isa(CI.getOperand(2)), "llvm.gcroot parameter #2 must be a constant.", &CI); @@ -1291,7 +1312,7 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { &CI); } break; case Intrinsic::init_trampoline: - Assert1(isa(IntrinsicInst::StripPointerCasts(CI.getOperand(2))), + Assert1(isa(CI.getOperand(2)->stripPointerCasts()), "llvm.init_trampoline parameter #2 must resolve to a function.", &CI); break; @@ -1321,7 +1342,7 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, // Note that "arg#0" is the return type. for (unsigned ArgNo = 0; ArgNo < Count; ++ArgNo) { - MVT::ValueType VT = va_arg(VA, MVT::ValueType); + int VT = va_arg(VA, int); // An MVT::SimpleValueType when non-negative. if (VT == MVT::isVoid && ArgNo > 0) { if (!FTy->isVarArg()) @@ -1341,8 +1362,8 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, EltTy = VTy->getElementType(); NumElts = VTy->getNumElements(); } - - if ((int)VT < 0) { + + if (VT < 0) { int Match = ~VT; if (Match == 0) { if (Ty != FTy->getReturnType()) { @@ -1393,7 +1414,7 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, Suffix += "."; if (EltTy != Ty) Suffix += "v" + utostr(NumElts); - Suffix += MVT::getValueTypeString(MVT::getValueType(EltTy)); + Suffix += MVT::getMVT(EltTy).getMVTString(); } else if (VT == MVT::iPTR) { if (!isa(Ty)) { if (ArgNo == 0) @@ -1404,19 +1425,20 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, "pointer and a pointer is required.", F); break; } - } else if (MVT::isVector(VT)) { + } else if (MVT((MVT::SimpleValueType)VT).isVector()) { + MVT VVT = MVT((MVT::SimpleValueType)VT); // If this is a vector argument, verify the number and type of elements. - if (MVT::getVectorElementType(VT) != MVT::getValueType(EltTy)) { + if (VVT.getVectorElementType() != MVT::getMVT(EltTy)) { CheckFailed("Intrinsic prototype has incorrect vector element type!", F); break; } - if (MVT::getVectorNumElements(VT) != NumElts) { + if (VVT.getVectorNumElements() != NumElts) { CheckFailed("Intrinsic prototype has incorrect number of " "vector elements!",F); break; } - } else if (MVT::getTypeForValueType(VT) != EltTy) { + } else if (MVT((MVT::SimpleValueType)VT).getTypeForMVT() != EltTy) { if (ArgNo == 0) CheckFailed("Intrinsic prototype has incorrect result type!", F); else @@ -1446,6 +1468,10 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, F->getName().substr(Name.length()) + "'. It should be '" + Suffix + "'", F); } + + // Check parameter attributes. + Assert1(F->getParamAttrs() == Intrinsic::getParamAttrs(ID), + "Intrinsic has wrong parameter attributes!", F); }