X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FVerifier.cpp;h=ffca88bfabc307a67c3f4ffc196f4298434698f4;hb=bb862c042fd773354645382ad0511b165b33116e;hp=052c963c1501d0b9d4081c444e2cb3815912c5b1;hpb=559d77afb30b72e6e62cec89def71a04b7504b11;p=oota-llvm.git diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 052c963c150..ffca88bfabc 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -46,6 +46,7 @@ #include "llvm/Pass.h" #include "llvm/Module.h" #include "llvm/ModuleProvider.h" +#include "llvm/ParameterAttributes.h" #include "llvm/DerivedTypes.h" #include "llvm/InlineAsm.h" #include "llvm/Instructions.h" @@ -69,12 +70,13 @@ namespace { // Anonymous namespace for class struct VISIBILITY_HIDDEN Verifier : public FunctionPass, InstVisitor { + static char ID; // Pass ID, replacement for typeid bool Broken; // Is this module found to be broken? bool RealPass; // Are we not being run by a PassManager? VerifierFailureAction action; // What to do if verification fails. Module *Mod; // Module we are verifying right now - ETForest *EF; // ET-Forest, caution can be null! + DominatorTree *DT; // Dominator Tree, caution can be null! std::stringstream msgs; // A stringstream to collect messages /// InstInThisBlock - when verifying a basic block, keep track of all of the @@ -84,18 +86,22 @@ namespace { // Anonymous namespace for class SmallPtrSet InstsInThisBlock; Verifier() - : Broken(false), RealPass(true), action(AbortProcessAction), - EF(0), msgs( std::ios::app | std::ios::out ) {} + : FunctionPass((intptr_t)&ID), + Broken(false), RealPass(true), action(AbortProcessAction), + DT(0), msgs( std::ios::app | std::ios::out ) {} Verifier( VerifierFailureAction ctn ) - : Broken(false), RealPass(true), action(ctn), EF(0), - msgs( std::ios::app | std::ios::out ) {} + : FunctionPass((intptr_t)&ID), + Broken(false), RealPass(true), action(ctn), DT(0), + msgs( std::ios::app | std::ios::out ) {} Verifier(bool AB ) - : Broken(false), RealPass(true), - action( AB ? AbortProcessAction : PrintMessageAction), EF(0), - msgs( std::ios::app | std::ios::out ) {} - Verifier(ETForest &ef) - : Broken(false), RealPass(false), action(PrintMessageAction), - EF(&ef), msgs( std::ios::app | std::ios::out ) {} + : FunctionPass((intptr_t)&ID), + Broken(false), RealPass(true), + action( AB ? AbortProcessAction : PrintMessageAction), DT(0), + msgs( std::ios::app | std::ios::out ) {} + Verifier(DominatorTree &dt) + : FunctionPass((intptr_t)&ID), + Broken(false), RealPass(false), action(PrintMessageAction), + DT(&dt), msgs( std::ios::app | std::ios::out ) {} bool doInitialization(Module &M) { @@ -112,8 +118,10 @@ namespace { // Anonymous namespace for class bool runOnFunction(Function &F) { // Get dominator information if we are being run by PassManager - if (RealPass) EF = &getAnalysis(); - + if (RealPass) DT = &getAnalysis(); + + Mod = F.getParent(); + visit(F); InstsInThisBlock.clear(); @@ -139,6 +147,10 @@ namespace { // Anonymous namespace for class I != E; ++I) visitGlobalVariable(*I); + for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); + I != E; ++I) + visitGlobalAlias(*I); + // If the module is broken, abort at this time. return abortIfBroken(); } @@ -146,7 +158,7 @@ namespace { // Anonymous namespace for class virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); if (RealPass) - AU.addRequired(); + AU.addRequired(); } /// abortIfBroken - If the module is broken and we are supposed to abort on @@ -177,6 +189,7 @@ namespace { // Anonymous namespace for class void verifyTypeSymbolTable(TypeSymbolTable &ST); void visitGlobalValue(GlobalValue &GV); void visitGlobalVariable(GlobalVariable &GV); + void visitGlobalAlias(GlobalAlias &GA); void visitFunction(Function &F); void visitBasicBlock(BasicBlock &BB); void visitTruncInst(TruncInst &I); @@ -254,6 +267,7 @@ namespace { // Anonymous namespace for class } }; + char Verifier::ID = 0; RegisterPass X("verify", "Module Verifier"); } // End anonymous namespace @@ -275,7 +289,9 @@ void Verifier::visitGlobalValue(GlobalValue &GV) { Assert1(!GV.isDeclaration() || GV.hasExternalLinkage() || GV.hasDLLImportLinkage() || - GV.hasExternalWeakLinkage(), + GV.hasExternalWeakLinkage() || + (isa(GV) && + (GV.hasInternalLinkage() || GV.hasWeakLinkage())), "Global is external, but doesn't have external or dllimport or weak linkage!", &GV); @@ -301,6 +317,26 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) { visitGlobalValue(GV); } +void Verifier::visitGlobalAlias(GlobalAlias &GA) { + Assert1(!GA.getName().empty(), + "Alias name cannot be empty!", &GA); + Assert1(GA.hasExternalLinkage() || GA.hasInternalLinkage() || + GA.hasWeakLinkage(), + "Alias should have external or external weak linkage!", &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 && + isa(CE->getOperand(0)), + "Aliasee should be either GlobalValue or bitcast of GlobalValue", + &GA); + } + + visitGlobalValue(GA); +} + void Verifier::verifyTypeSymbolTable(TypeSymbolTable &ST) { } @@ -323,6 +359,45 @@ void Verifier::visitFunction(Function &F) { FT->getNumParams() > 0 && isa(FT->getParamType(0))), "Invalid struct-return function!", &F); + if (const ParamAttrsList *Attrs = FT->getParamAttrs()) { + unsigned Idx = 1; + + Assert1(!Attrs->paramHasAttr(0, ParamAttr::ByVal), + "Attribute ByVal should not apply to functions!", &F); + Assert1(!Attrs->paramHasAttr(0, ParamAttr::StructRet), + "Attribute SRet should not apply to functions!", &F); + Assert1(!Attrs->paramHasAttr(0, ParamAttr::InReg), + "Attribute InReg should not apply to functions!", &F); + + for (FunctionType::param_iterator I = FT->param_begin(), + E = FT->param_end(); I != E; ++I, ++Idx) { + if (Attrs->paramHasAttr(Idx, ParamAttr::ZExt) || + Attrs->paramHasAttr(Idx, ParamAttr::SExt)) + Assert1(FT->getParamType(Idx-1)->isInteger(), + "Attribute ZExt should only apply to Integer type!", &F); + if (Attrs->paramHasAttr(Idx, ParamAttr::NoAlias)) + Assert1(isa(FT->getParamType(Idx-1)), + "Attribute NoAlias should only apply to Pointer type!", &F); + if (Attrs->paramHasAttr(Idx, ParamAttr::ByVal)) { + Assert1(isa(FT->getParamType(Idx-1)), + "Attribute ByVal should only apply to pointer to structs!", &F); + + Assert1(!Attrs->paramHasAttr(Idx, ParamAttr::StructRet), + "Attributes ByVal and StructRet are incompatible!", &F); + + const PointerType *Ty = + cast(FT->getParamType(Idx-1)); + Assert1(isa(Ty->getElementType()), + "Attribute ByVal should only apply to pointer to structs!", &F); + } + + Assert1(!Attrs->paramHasAttr(Idx, ParamAttr::NoReturn), + "Attribute NoReturn should only be applied to function", &F); + Assert1(!Attrs->paramHasAttr(Idx, ParamAttr::NoUnwind), + "Attribute NoUnwind should only be applied to function", &F); + } + } + // Check that this function meets the restrictions on this calling convention. switch (F.getCallingConv()) { default: @@ -640,7 +715,8 @@ void Verifier::visitPHINode(PHINode &PN) { // This can be tested by checking whether the instruction before this is // either nonexistent (because this is begin()) or is a PHI node. If not, // then there is some other instruction before a PHI. - Assert2(&PN.getParent()->front() == &PN || isa(PN.getPrev()), + Assert2(&PN == &PN.getParent()->front() || + isa(--BasicBlock::iterator(&PN)), "PHI nodes not grouped at top of basic block!", &PN, PN.getParent()); @@ -828,7 +904,7 @@ void Verifier::visitInstruction(Instruction &I) { for (Value::use_iterator UI = I.use_begin(), UE = I.use_end(); UI != UE; ++UI) Assert1(*UI != (User*)&I || - !EF->dominates(&BB->getParent()->getEntryBlock(), BB), + !DT->dominates(&BB->getParent()->getEntryBlock(), BB), "Only PHI nodes may reference their own value!", &I); } @@ -866,12 +942,17 @@ void Verifier::visitInstruction(Instruction &I) { // taken. Assert1(!F->isIntrinsic() || (i == 0 && isa(I)), "Cannot take the address of an intrinsic!", &I); + Assert1(F->getParent() == Mod, "Referencing function in another module!", + &I); } else if (BasicBlock *OpBB = dyn_cast(I.getOperand(i))) { Assert1(OpBB->getParent() == BB->getParent(), "Referring to a basic block in another function!", &I); } else if (Argument *OpArg = dyn_cast(I.getOperand(i))) { Assert1(OpArg->getParent() == BB->getParent(), "Referring to an argument in another function!", &I); + } else if (GlobalValue *GV = dyn_cast(I.getOperand(i))) { + Assert1(GV->getParent() == Mod, "Referencing global in another module!", + &I); } else if (Instruction *Op = dyn_cast(I.getOperand(i))) { BasicBlock *OpBlock = Op->getParent(); @@ -892,7 +973,7 @@ void Verifier::visitInstruction(Instruction &I) { // dominates all of it's predecessors (other than the invoke) or if // the invoke value is only used by a phi in the successor. if (!OpBlock->getSinglePredecessor() && - EF->dominates(&BB->getParent()->getEntryBlock(), BB)) { + DT->dominates(&BB->getParent()->getEntryBlock(), BB)) { // The first case we allow is if the use is a PHI operand in the // normal block, and if that PHI operand corresponds to the invoke's // block. @@ -909,7 +990,7 @@ void Verifier::visitInstruction(Instruction &I) { Bad = false; for (pred_iterator PI = pred_begin(OpBlock), E = pred_end(OpBlock); PI != E; ++PI) { - if (*PI != II->getParent() && !EF->dominates(OpBlock, *PI)) { + if (*PI != II->getParent() && !DT->dominates(OpBlock, *PI)) { Bad = true; break; } @@ -923,20 +1004,20 @@ void Verifier::visitInstruction(Instruction &I) { // If they are in the same basic block, make sure that the definition // comes before the use. Assert2(InstsInThisBlock.count(Op) || - !EF->dominates(&BB->getParent()->getEntryBlock(), BB), + !DT->dominates(&BB->getParent()->getEntryBlock(), BB), "Instruction does not dominate all uses!", Op, &I); } // Definition must dominate use unless use is unreachable! - Assert2(EF->dominates(OpBlock, BB) || - !EF->dominates(&BB->getParent()->getEntryBlock(), BB), + Assert2(DT->dominates(OpBlock, BB) || + !DT->dominates(&BB->getParent()->getEntryBlock(), BB), "Instruction does not dominate all uses!", Op, &I); } else { // PHI nodes are more difficult than other nodes because they actually // "use" the value in the predecessor basic blocks they correspond to. BasicBlock *PredBB = cast(I.getOperand(i+1)); - Assert2(EF->dominates(OpBlock, PredBB) || - !EF->dominates(&BB->getParent()->getEntryBlock(), PredBB), + Assert2(DT->dominates(OpBlock, PredBB) || + !DT->dominates(&BB->getParent()->getEntryBlock(), PredBB), "Instruction does not dominate all uses!", Op, &I); } } else if (isa(I.getOperand(i))) { @@ -951,7 +1032,8 @@ void Verifier::visitInstruction(Instruction &I) { /// void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { Function *IF = CI.getCalledFunction(); - Assert1(IF->isDeclaration(), "Intrinsic functions should never be defined!", IF); + Assert1(IF->isDeclaration(), "Intrinsic functions should never be defined!", + IF); #define GET_INTRINSIC_VERIFIER #include "llvm/Intrinsics.gen" @@ -1027,17 +1109,20 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F, ...) { case Intrinsic::bswap: if (GotBits < 16 || GotBits % 16 != 0) CheckFailed("Intrinsic requires even byte width argument", F); + /* FALL THROUGH */ + case Intrinsic::part_set: + case Intrinsic::part_select: if (ArgNo == 1) { unsigned ResultBits = cast(FTy->getReturnType())->getBitWidth(); if (GotBits != ResultBits) - CheckFailed("Intrinsic requires parameter and result bit " - "widths to match", F); + CheckFailed("Intrinsic requires the bit widths of the first " + "parameter and the result to match", F); } break; } } else if (TypeID == Type::VectorTyID) { - // If this is a packed argument, verify the number and type of elements. + // If this is a vector argument, verify the number and type of elements. const VectorType *PTy = cast(Ty); int ElemTy = va_arg(VA, int); if (ElemTy != PTy->getElementType()->getTypeID()) {