X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FVMCore%2FVerifier.cpp;h=e2ccb5b12b99fed706ca20babc9e407821f6ffff;hb=2751e76a709738590242adce47a3b55bc77fd36d;hp=b7173e4e905cddca45ba99e8258a4a5337ad8402;hpb=7334f2e3daf011cb187dd46067a2cdbfd8f8133e;p=oota-llvm.git diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index b7173e4e905..e2ccb5b12b9 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -57,8 +57,7 @@ #include "llvm/Support/InstVisitor.h" #include "Support/STLExtras.h" #include - -namespace llvm { +using namespace llvm; namespace { // Anonymous namespace for class @@ -109,8 +108,7 @@ namespace { // Anonymous namespace for class visitGlobalValue(*I); for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I) - if (I->isExternal() && I->hasInternalLinkage()) - CheckFailed("Global Variable is external with internal linkage!", I); + visitGlobalValue(*I); // If the module is broken, abort at this time. abortIfBroken(); @@ -155,23 +153,39 @@ namespace { // Anonymous namespace for class void visitUserOp2(Instruction &I) { visitUserOp1(I); } void visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI); + + void WriteValue(const Value *V) { + if (!V) return; + if (isa(V)) { + std::cerr << *V; + } else if (const Type *Ty = dyn_cast(V)) { + WriteTypeSymbolic(std::cerr, Ty, Mod); + } else { + WriteAsOperand (std::cerr, V, true, true, Mod); + std::cerr << "\n"; + } + } + + // CheckFailed - A check failed, so print out the condition and the message // that failed. This provides a nice place to put a breakpoint if you want // to see why something is not correct. // - inline void CheckFailed(const std::string &Message, - const Value *V1 = 0, const Value *V2 = 0, - const Value *V3 = 0, const Value *V4 = 0) { + void CheckFailed(const std::string &Message, + const Value *V1 = 0, const Value *V2 = 0, + const Value *V3 = 0, const Value *V4 = 0) { std::cerr << Message << "\n"; - if (V1) { WriteAsOperand (std::cerr, V1, true, true, Mod); std::cerr << "\n"; } - if (V2) { WriteAsOperand (std::cerr, V2, true, true, Mod); std::cerr << "\n"; } - if (V3) { WriteAsOperand (std::cerr, V3, true, true, Mod); std::cerr << "\n"; } - if (V4) { WriteAsOperand (std::cerr, V4, true, true, Mod); std::cerr << "\n"; } + WriteValue(V1); + WriteValue(V2); + WriteValue(V3); + WriteValue(V4); Broken = true; } }; RegisterOpt X("verify", "Module Verifier"); +} // End anonymous namespace + // Assert - We know that cond should be true, if not print an error message. #define Assert(C, M) \ @@ -188,7 +202,7 @@ namespace { // Anonymous namespace for class void Verifier::visitGlobalValue(GlobalValue &GV) { Assert1(!GV.isExternal() || GV.hasExternalLinkage(), - "Global value has Internal Linkage!", &GV); + "Global is external, but doesn't have external linkage!", &GV); Assert1(!GV.hasAppendingLinkage() || isa(GV), "Only global variables can have appending linkage!", &GV); @@ -227,6 +241,9 @@ void Verifier::visitFunction(Function &F) { Assert2(FT->getNumParams() == NumArgs, "# formal arguments must match # of arguments for function type!", &F, FT); + Assert1(F.getReturnType()->isFirstClassType() || + F.getReturnType() == Type::VoidTy, + "Functions cannot return aggregate values!", &F); // Check that the argument values match the function type for this function... unsigned i = 0; @@ -489,18 +506,25 @@ void Verifier::visitInstruction(Instruction &I) { "Cannot take the address of an intrinsic!", &I); else if (Instruction *Op = dyn_cast(I.getOperand(i))) { + BasicBlock *OpBlock = Op->getParent(); + // Check that a definition dominates all of its uses. // if (!isa(I)) { + // Invoke results are only usable in the normal destination, not in the + // exceptional destination. + if (InvokeInst *II = dyn_cast(Op)) + OpBlock = II->getNormalDest(); + // Definition must dominate use unless use is unreachable! - Assert2(DS->dominates(Op->getParent(), BB) || + Assert2(DS->dominates(OpBlock, BB) || !DS->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(DS->dominates(Op->getParent(), PredBB) || + Assert2(DS->dominates(OpBlock, PredBB) || !DS->dominates(&BB->getParent()->getEntryBlock(), PredBB), "Instruction does not dominate all uses!", Op, &I); } @@ -531,6 +555,15 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { case Intrinsic::longjmp: NumArgs = 2; break; case Intrinsic::sigsetjmp: NumArgs = 2; break; case Intrinsic::siglongjmp: NumArgs = 2; break; + + case Intrinsic::dbg_stoppoint: NumArgs = 4; break; + case Intrinsic::dbg_region_start:NumArgs = 1; break; + case Intrinsic::dbg_region_end: NumArgs = 1; break; + case Intrinsic::dbg_func_start: NumArgs = 1; break; + case Intrinsic::dbg_declare: NumArgs = 1; break; + + case Intrinsic::memcpy: NumArgs = 4; break; + case Intrinsic::memmove: NumArgs = 4; break; case Intrinsic::alpha_ctlz: NumArgs = 1; break; case Intrinsic::alpha_cttz: NumArgs = 1; break; @@ -557,19 +590,18 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { "Illegal # arguments for intrinsic function!", IF); } -} // End anonymous namespace //===----------------------------------------------------------------------===// // Implement the public interfaces to this file... //===----------------------------------------------------------------------===// -FunctionPass *createVerifierPass() { +FunctionPass *llvm::createVerifierPass() { return new Verifier(); } // verifyFunction - Create -bool verifyFunction(const Function &f) { +bool llvm::verifyFunction(const Function &f) { Function &F = (Function&)f; assert(!F.isExternal() && "Cannot verify external functions"); @@ -588,12 +620,10 @@ bool verifyFunction(const Function &f) { // verifyModule - Check a module for errors, printing messages on stderr. // Return true if the module is corrupt. // -bool verifyModule(const Module &M) { +bool llvm::verifyModule(const Module &M) { PassManager PM; Verifier *V = new Verifier(); PM.add(V); PM.run((Module&)M); return V->Broken; } - -} // End llvm namespace