X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FIR%2FVerifier.cpp;h=089ad1ca5f2500e6cd3f4ce7299ee7fbc4f8a9cf;hb=193c3e91b9e5c0d2fe68b29d4d4eb01f14ce36ee;hp=9e150e857561d2d4c09069954e76e2846ea9d848;hpb=7f2eff792a2e18758a25956abdac2440ee18dd7f;p=oota-llvm.git diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index 9e150e85756..089ad1ca5f2 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -51,24 +51,24 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/DebugInfo.h" +#include "llvm/IR/CFG.h" +#include "llvm/IR/CallSite.h" #include "llvm/IR/CallingConv.h" +#include "llvm/IR/ConstantRange.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DebugInfo.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/InlineAsm.h" +#include "llvm/IR/InstVisitor.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" -#include "llvm/InstVisitor.h" +#include "llvm/IR/PassManager.h" #include "llvm/Pass.h" -#include "llvm/PassManager.h" -#include "llvm/Support/CFG.h" -#include "llvm/Support/CallSite.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/ConstantRange.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" @@ -79,325 +79,258 @@ using namespace llvm; static cl::opt DisableDebugInfoVerifier("disable-debug-info-verifier", cl::init(true)); -namespace { // Anonymous namespace for class - struct PreVerifier : public FunctionPass { - static char ID; // Pass ID, replacement for typeid - - PreVerifier() : FunctionPass(ID) { - initializePreVerifierPass(*PassRegistry::getPassRegistry()); - } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - } - - // Check that the prerequisites for successful DominatorTree construction - // are satisfied. - bool runOnFunction(Function &F) { - bool Broken = false; - - for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) { - if (I->empty() || !I->back().isTerminator()) { - dbgs() << "Basic Block in function '" << F.getName() - << "' does not have terminator!\n"; - I->printAsOperand(dbgs(), true); - dbgs() << "\n"; - Broken = true; - } - } - - if (Broken) - report_fatal_error("Broken module, no Basic Block terminator!"); - - return false; - } - }; -} - -char PreVerifier::ID = 0; -INITIALIZE_PASS(PreVerifier, "preverify", "Preliminary module verification", - false, false) -static char &PreVerifyID = PreVerifier::ID; - namespace { - struct Verifier : public FunctionPass, public InstVisitor { - static char ID; // Pass ID, replacement for typeid - bool Broken; // Is this module found to be broken? - VerifierFailureAction action; - // What to do if verification fails. - Module *Mod; // Module we are verifying right now - LLVMContext *Context; // Context within which we are verifying - DominatorTree *DT; // Dominator Tree, caution can be null! - const DataLayout *DL; - - std::string Messages; - raw_string_ostream MessagesStr; - - /// InstInThisBlock - when verifying a basic block, keep track of all of the - /// instructions we have seen so far. This allows us to do efficient - /// dominance checks for the case when an instruction has an operand that is - /// an instruction in the same block. - SmallPtrSet InstsInThisBlock; - - /// MDNodes - keep track of the metadata nodes that have been checked - /// already. - SmallPtrSet MDNodes; - - /// PersonalityFn - The personality function referenced by the - /// LandingPadInsts. All LandingPadInsts within the same function must use - /// the same personality function. - const Value *PersonalityFn; - - /// Finder keeps track of all debug info MDNodes in a Module. - DebugInfoFinder Finder; - - Verifier() - : FunctionPass(ID), Broken(false), - action(AbortProcessAction), Mod(0), Context(0), DT(0), DL(0), - MessagesStr(Messages), PersonalityFn(0) { - initializeVerifierPass(*PassRegistry::getPassRegistry()); +class Verifier : public InstVisitor { + friend class InstVisitor; + + raw_ostream &OS; + const Module *M; + LLVMContext *Context; + const DataLayout *DL; + DominatorTree DT; + + /// \brief When verifying a basic block, keep track of all of the + /// instructions we have seen so far. + /// + /// This allows us to do efficient dominance checks for the case when an + /// instruction has an operand that is an instruction in the same block. + SmallPtrSet InstsInThisBlock; + + /// \brief Keep track of the metadata nodes that have been checked already. + SmallPtrSet MDNodes; + + /// \brief The personality function referenced by the LandingPadInsts. + /// All LandingPadInsts within the same function must use the same + /// personality function. + const Value *PersonalityFn; + + /// \brief Finder keeps track of all debug info MDNodes in a Module. + DebugInfoFinder Finder; + + /// \brief Track the brokenness of the module while recursively visiting. + bool Broken; + +public: + explicit Verifier(raw_ostream &OS = dbgs()) + : OS(OS), M(0), Context(0), DL(0), PersonalityFn(0), Broken(false) {} + + bool verify(const Function &F) { + M = F.getParent(); + Context = &M->getContext(); + + // First ensure the function is well-enough formed to compute dominance + // information. + if (F.empty()) { + OS << "Function '" << F.getName() + << "' does not contain an entry block!\n"; + return false; } - explicit Verifier(VerifierFailureAction ctn) - : FunctionPass(ID), Broken(false), action(ctn), Mod(0), - Context(0), DT(0), DL(0), MessagesStr(Messages), PersonalityFn(0) { - initializeVerifierPass(*PassRegistry::getPassRegistry()); + for (Function::const_iterator I = F.begin(), E = F.end(); I != E; ++I) { + if (I->empty() || !I->back().isTerminator()) { + OS << "Basic Block in function '" << F.getName() + << "' does not have terminator!\n"; + I->printAsOperand(OS, true); + OS << "\n"; + return false; + } } - bool doInitialization(Module &M) { - Mod = &M; - Context = &M.getContext(); + // Now directly compute a dominance tree. We don't rely on the pass + // manager to provide this as it isolates us from a potentially + // out-of-date dominator tree and makes it significantly more complex to + // run this code outside of a pass manager. + // FIXME: It's really gross that we have to cast away constness here. + DT.recalculate(const_cast(F)); - DL = getAnalysisIfAvailable(); - - // We must abort before returning back to the pass manager, or else the - // pass manager may try to run other passes on the broken module. - return abortIfBroken(); - } + Finder.reset(); + Broken = false; + // FIXME: We strip const here because the inst visitor strips const. + visit(const_cast(F)); + InstsInThisBlock.clear(); + PersonalityFn = 0; - bool runOnFunction(Function &F) { - // Get dominator information if we are being run by PassManager - DT = &getAnalysis().getDomTree(); + if (!DisableDebugInfoVerifier) + // Verify Debug Info. + verifyDebugInfo(); - Mod = F.getParent(); - if (!Context) Context = &F.getContext(); + return !Broken; + } - Finder.reset(); - visit(F); - InstsInThisBlock.clear(); - PersonalityFn = 0; + bool verify(const Module &M) { + this->M = &M; + Context = &M.getContext(); + Finder.reset(); + Broken = false; - if (!DisableDebugInfoVerifier) - // Verify Debug Info. - verifyDebugInfo(); + // Scan through, checking all of the external function's linkage now... + for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) { + visitGlobalValue(*I); - // We must abort before returning back to the pass manager, or else the - // pass manager may try to run other passes on the broken module. - return abortIfBroken(); + // Check to make sure function prototypes are okay. + if (I->isDeclaration()) + visitFunction(*I); } - bool doFinalization(Module &M) { - // Scan through, checking all of the external function's linkage now... - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { - visitGlobalValue(*I); - - // Check to make sure function prototypes are okay. - if (I->isDeclaration()) visitFunction(*I); - } - - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) - visitGlobalVariable(*I); - - for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); - I != E; ++I) - visitGlobalAlias(*I); - - for (Module::named_metadata_iterator I = M.named_metadata_begin(), - E = M.named_metadata_end(); I != E; ++I) - visitNamedMDNode(*I); + for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) + visitGlobalVariable(*I); - visitModuleFlags(M); - visitModuleIdents(M); + for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end(); + I != E; ++I) + visitGlobalAlias(*I); - if (!DisableDebugInfoVerifier) { - Finder.reset(); - Finder.processModule(M); - // Verify Debug Info. - verifyDebugInfo(); - } - - // If the module is broken, abort at this time. - return abortIfBroken(); - } + for (Module::const_named_metadata_iterator I = M.named_metadata_begin(), + E = M.named_metadata_end(); + I != E; ++I) + visitNamedMDNode(*I); - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AU.addRequiredID(PreVerifyID); - AU.addRequired(); - } + visitModuleFlags(M); + visitModuleIdents(M); - /// abortIfBroken - If the module is broken and we are supposed to abort on - /// this condition, do so. - /// - bool abortIfBroken() { - if (!Broken) return false; - MessagesStr << "Broken module found, "; - switch (action) { - case AbortProcessAction: - MessagesStr << "compilation aborted!\n"; - dbgs() << MessagesStr.str(); - // Client should choose different reaction if abort is not desired - abort(); - case PrintMessageAction: - MessagesStr << "verification continues.\n"; - dbgs() << MessagesStr.str(); - return false; - case ReturnStatusAction: - MessagesStr << "compilation terminated.\n"; - return true; - } - llvm_unreachable("Invalid action"); + if (!DisableDebugInfoVerifier) { + Finder.reset(); + Finder.processModule(M); + // Verify Debug Info. + verifyDebugInfo(); } + return !Broken; + } - // Verification methods... - void visitGlobalValue(GlobalValue &GV); - void visitGlobalVariable(GlobalVariable &GV); - void visitGlobalAlias(GlobalAlias &GA); - void visitNamedMDNode(NamedMDNode &NMD); - void visitMDNode(MDNode &MD, Function *F); - void visitModuleIdents(Module &M); - void visitModuleFlags(Module &M); - void visitModuleFlag(MDNode *Op, DenseMap &SeenIDs, - SmallVectorImpl &Requirements); - void visitFunction(Function &F); - void visitBasicBlock(BasicBlock &BB); - using InstVisitor::visit; - - void visit(Instruction &I); - - void visitTruncInst(TruncInst &I); - void visitZExtInst(ZExtInst &I); - void visitSExtInst(SExtInst &I); - void visitFPTruncInst(FPTruncInst &I); - void visitFPExtInst(FPExtInst &I); - void visitFPToUIInst(FPToUIInst &I); - void visitFPToSIInst(FPToSIInst &I); - void visitUIToFPInst(UIToFPInst &I); - void visitSIToFPInst(SIToFPInst &I); - void visitIntToPtrInst(IntToPtrInst &I); - void visitPtrToIntInst(PtrToIntInst &I); - void visitBitCastInst(BitCastInst &I); - void visitAddrSpaceCastInst(AddrSpaceCastInst &I); - void visitPHINode(PHINode &PN); - void visitBinaryOperator(BinaryOperator &B); - void visitICmpInst(ICmpInst &IC); - void visitFCmpInst(FCmpInst &FC); - void visitExtractElementInst(ExtractElementInst &EI); - void visitInsertElementInst(InsertElementInst &EI); - void visitShuffleVectorInst(ShuffleVectorInst &EI); - void visitVAArgInst(VAArgInst &VAA) { visitInstruction(VAA); } - void visitCallInst(CallInst &CI); - void visitInvokeInst(InvokeInst &II); - void visitGetElementPtrInst(GetElementPtrInst &GEP); - void visitLoadInst(LoadInst &LI); - void visitStoreInst(StoreInst &SI); - void verifyDominatesUse(Instruction &I, unsigned i); - void visitInstruction(Instruction &I); - void visitTerminatorInst(TerminatorInst &I); - void visitBranchInst(BranchInst &BI); - void visitReturnInst(ReturnInst &RI); - void visitSwitchInst(SwitchInst &SI); - void visitIndirectBrInst(IndirectBrInst &BI); - void visitSelectInst(SelectInst &SI); - void visitUserOp1(Instruction &I); - void visitUserOp2(Instruction &I) { visitUserOp1(I); } - void visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI); - void visitAtomicCmpXchgInst(AtomicCmpXchgInst &CXI); - void visitAtomicRMWInst(AtomicRMWInst &RMWI); - void visitFenceInst(FenceInst &FI); - void visitAllocaInst(AllocaInst &AI); - void visitExtractValueInst(ExtractValueInst &EVI); - void visitInsertValueInst(InsertValueInst &IVI); - void visitLandingPadInst(LandingPadInst &LPI); - - void VerifyCallSite(CallSite CS); - bool PerformTypeCheck(Intrinsic::ID ID, Function *F, Type *Ty, - int VT, unsigned ArgNo, std::string &Suffix); - bool VerifyIntrinsicType(Type *Ty, - ArrayRef &Infos, - SmallVectorImpl &ArgTys); - bool VerifyIntrinsicIsVarArg(bool isVarArg, - ArrayRef &Infos); - bool VerifyAttributeCount(AttributeSet Attrs, unsigned Params); - void VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx, - bool isFunction, const Value *V); - void VerifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty, - bool isReturnValue, const Value *V); - void VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs, - const Value *V); - - void VerifyBitcastType(const Value *V, Type *DestTy, Type *SrcTy); - void VerifyConstantExprBitcastType(const ConstantExpr *CE); - - void verifyDebugInfo(); - - void WriteValue(const Value *V) { - if (!V) return; - if (isa(V)) { - MessagesStr << *V << '\n'; - } else { - V->printAsOperand(MessagesStr, true, Mod); - MessagesStr << '\n'; - } - } - - void WriteType(Type *T) { - if (!T) return; - MessagesStr << ' ' << *T; +private: + // Verification methods... + void visitGlobalValue(const GlobalValue &GV); + void visitGlobalVariable(const GlobalVariable &GV); + void visitGlobalAlias(const GlobalAlias &GA); + void visitNamedMDNode(const NamedMDNode &NMD); + void visitMDNode(MDNode &MD, Function *F); + void visitModuleIdents(const Module &M); + void visitModuleFlags(const Module &M); + void visitModuleFlag(const MDNode *Op, + DenseMap &SeenIDs, + SmallVectorImpl &Requirements); + void visitFunction(const Function &F); + void visitBasicBlock(BasicBlock &BB); + + // InstVisitor overrides... + using InstVisitor::visit; + void visit(Instruction &I); + + void visitTruncInst(TruncInst &I); + void visitZExtInst(ZExtInst &I); + void visitSExtInst(SExtInst &I); + void visitFPTruncInst(FPTruncInst &I); + void visitFPExtInst(FPExtInst &I); + void visitFPToUIInst(FPToUIInst &I); + void visitFPToSIInst(FPToSIInst &I); + void visitUIToFPInst(UIToFPInst &I); + void visitSIToFPInst(SIToFPInst &I); + void visitIntToPtrInst(IntToPtrInst &I); + void visitPtrToIntInst(PtrToIntInst &I); + void visitBitCastInst(BitCastInst &I); + void visitAddrSpaceCastInst(AddrSpaceCastInst &I); + void visitPHINode(PHINode &PN); + void visitBinaryOperator(BinaryOperator &B); + void visitICmpInst(ICmpInst &IC); + void visitFCmpInst(FCmpInst &FC); + void visitExtractElementInst(ExtractElementInst &EI); + void visitInsertElementInst(InsertElementInst &EI); + void visitShuffleVectorInst(ShuffleVectorInst &EI); + void visitVAArgInst(VAArgInst &VAA) { visitInstruction(VAA); } + void visitCallInst(CallInst &CI); + void visitInvokeInst(InvokeInst &II); + void visitGetElementPtrInst(GetElementPtrInst &GEP); + void visitLoadInst(LoadInst &LI); + void visitStoreInst(StoreInst &SI); + void verifyDominatesUse(Instruction &I, unsigned i); + void visitInstruction(Instruction &I); + void visitTerminatorInst(TerminatorInst &I); + void visitBranchInst(BranchInst &BI); + void visitReturnInst(ReturnInst &RI); + void visitSwitchInst(SwitchInst &SI); + void visitIndirectBrInst(IndirectBrInst &BI); + void visitSelectInst(SelectInst &SI); + void visitUserOp1(Instruction &I); + void visitUserOp2(Instruction &I) { visitUserOp1(I); } + void visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI); + void visitAtomicCmpXchgInst(AtomicCmpXchgInst &CXI); + void visitAtomicRMWInst(AtomicRMWInst &RMWI); + void visitFenceInst(FenceInst &FI); + void visitAllocaInst(AllocaInst &AI); + void visitExtractValueInst(ExtractValueInst &EVI); + void visitInsertValueInst(InsertValueInst &IVI); + void visitLandingPadInst(LandingPadInst &LPI); + + void VerifyCallSite(CallSite CS); + bool PerformTypeCheck(Intrinsic::ID ID, Function *F, Type *Ty, int VT, + unsigned ArgNo, std::string &Suffix); + bool VerifyIntrinsicType(Type *Ty, ArrayRef &Infos, + SmallVectorImpl &ArgTys); + bool VerifyIntrinsicIsVarArg(bool isVarArg, + ArrayRef &Infos); + bool VerifyAttributeCount(AttributeSet Attrs, unsigned Params); + void VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx, bool isFunction, + const Value *V); + void VerifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty, + bool isReturnValue, const Value *V); + void VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs, + const Value *V); + + void VerifyBitcastType(const Value *V, Type *DestTy, Type *SrcTy); + void VerifyConstantExprBitcastType(const ConstantExpr *CE); + + void verifyDebugInfo(); + + void WriteValue(const Value *V) { + if (!V) + return; + if (isa(V)) { + OS << *V << '\n'; + } else { + V->printAsOperand(OS, true, M); + OS << '\n'; } + } + void WriteType(Type *T) { + if (!T) + return; + OS << ' ' << *T; + } - // 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. - void CheckFailed(const Twine &Message, - const Value *V1 = 0, const Value *V2 = 0, - const Value *V3 = 0, const Value *V4 = 0) { - MessagesStr << Message.str() << "\n"; - WriteValue(V1); - WriteValue(V2); - WriteValue(V3); - WriteValue(V4); - Broken = true; - } + // 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. + void CheckFailed(const Twine &Message, const Value *V1 = 0, + const Value *V2 = 0, const Value *V3 = 0, + const Value *V4 = 0) { + OS << Message.str() << "\n"; + WriteValue(V1); + WriteValue(V2); + WriteValue(V3); + WriteValue(V4); + Broken = true; + } - void CheckFailed(const Twine &Message, const Value *V1, - Type *T2, const Value *V3 = 0) { - MessagesStr << Message.str() << "\n"; - WriteValue(V1); - WriteType(T2); - WriteValue(V3); - Broken = true; - } + void CheckFailed(const Twine &Message, const Value *V1, Type *T2, + const Value *V3 = 0) { + OS << Message.str() << "\n"; + WriteValue(V1); + WriteType(T2); + WriteValue(V3); + Broken = true; + } - void CheckFailed(const Twine &Message, Type *T1, - Type *T2 = 0, Type *T3 = 0) { - MessagesStr << Message.str() << "\n"; - WriteType(T1); - WriteType(T2); - WriteType(T3); - Broken = true; - } - }; + void CheckFailed(const Twine &Message, Type *T1, Type *T2 = 0, Type *T3 = 0) { + OS << Message.str() << "\n"; + WriteType(T1); + WriteType(T2); + WriteType(T3); + Broken = true; + } +}; } // End anonymous namespace -char Verifier::ID = 0; -INITIALIZE_PASS_BEGIN(Verifier, "verify", "Module Verifier", false, false) -INITIALIZE_PASS_DEPENDENCY(PreVerifier) -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) -INITIALIZE_PASS_END(Verifier, "verify", "Module Verifier", false, false) - // Assert - We know that cond should be true, if not print an error message. #define Assert(C, M) \ do { if (!(C)) { CheckFailed(M); return; } } while (0) @@ -417,31 +350,27 @@ void Verifier::visit(Instruction &I) { } -void Verifier::visitGlobalValue(GlobalValue &GV) { +void Verifier::visitGlobalValue(const GlobalValue &GV) { Assert1(!GV.isDeclaration() || GV.isMaterializable() || GV.hasExternalLinkage() || - GV.hasDLLImportLinkage() || GV.hasExternalWeakLinkage() || (isa(GV) && (GV.hasLocalLinkage() || GV.hasWeakLinkage())), - "Global is external, but doesn't have external or dllimport or weak linkage!", + "Global is external, but doesn't have external or weak linkage!", &GV); - Assert1(!GV.hasDLLImportLinkage() || GV.isDeclaration(), - "Global is marked as dllimport, but not external", &GV); - Assert1(!GV.hasAppendingLinkage() || isa(GV), "Only global variables can have appending linkage!", &GV); if (GV.hasAppendingLinkage()) { - GlobalVariable *GVar = dyn_cast(&GV); + const GlobalVariable *GVar = dyn_cast(&GV); Assert1(GVar && GVar->getType()->getElementType()->isArrayTy(), "Only global arrays can have appending linkage!", GVar); } } -void Verifier::visitGlobalVariable(GlobalVariable &GV) { +void Verifier::visitGlobalVariable(const GlobalVariable &GV) { if (GV.hasInitializer()) { Assert1(GV.getInitializer()->getType() == GV.getType()->getElementType(), "Global variable initializer type does not match global " @@ -456,8 +385,7 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) { &GV); } } else { - Assert1(GV.hasExternalLinkage() || GV.hasDLLImportLinkage() || - GV.hasExternalWeakLinkage(), + Assert1(GV.hasExternalLinkage() || GV.hasExternalWeakLinkage(), "invalid linkage type for global declaration", &GV); } @@ -487,8 +415,8 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) { PointerType *PTy = dyn_cast(ATy->getElementType()); Assert1(PTy, "wrong type for intrinsic global variable", &GV); if (GV.hasInitializer()) { - Constant *Init = GV.getInitializer(); - ConstantArray *InitArray = dyn_cast(Init); + const Constant *Init = GV.getInitializer(); + const ConstantArray *InitArray = dyn_cast(Init); Assert1(InitArray, "wrong initalizer for intrinsic global variable", Init); for (unsigned i = 0, e = InitArray->getNumOperands(); i != e; ++i) { @@ -502,6 +430,11 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) { } } + Assert1(!GV.hasDLLImportStorageClass() || + (GV.isDeclaration() && GV.hasExternalLinkage()) || + GV.hasAvailableExternallyLinkage(), + "Global is marked as dllimport, but not external", &GV); + if (!GV.hasInitializer()) { visitGlobalValue(GV); return; @@ -532,7 +465,7 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) { visitGlobalValue(GV); } -void Verifier::visitGlobalAlias(GlobalAlias &GA) { +void Verifier::visitGlobalAlias(const GlobalAlias &GA) { Assert1(!GA.getName().empty(), "Alias name cannot be empty!", &GA); Assert1(GlobalAlias::isValidLinkage(GA.getLinkage()), @@ -542,22 +475,25 @@ void Verifier::visitGlobalAlias(GlobalAlias &GA) { Assert1(GA.getType() == GA.getAliasee()->getType(), "Alias and aliasee types should match!", &GA); Assert1(!GA.hasUnnamedAddr(), "Alias cannot have unnamed_addr!", &GA); + Assert1(!GA.hasSection(), "Alias cannot have a section!", &GA); + Assert1(!GA.getAlignment(), "Alias connot have an alignment", &GA); + + const Constant *Aliasee = GA.getAliasee(); + const GlobalValue *GV = dyn_cast(Aliasee); - Constant *Aliasee = GA.getAliasee(); - - if (!isa(Aliasee)) { - ConstantExpr *CE = dyn_cast(Aliasee); - Assert1(CE && - (CE->getOpcode() == Instruction::BitCast || - CE->getOpcode() == Instruction::AddrSpaceCast || - CE->getOpcode() == Instruction::GetElementPtr) && - isa(CE->getOperand(0)), - "Aliasee should be either GlobalValue, bitcast or " - "addrspacecast of GlobalValue", + if (!GV) { + const ConstantExpr *CE = dyn_cast(Aliasee); + if (CE && (CE->getOpcode() == Instruction::BitCast || + CE->getOpcode() == Instruction::AddrSpaceCast || + CE->getOpcode() == Instruction::GetElementPtr)) + GV = dyn_cast(CE->getOperand(0)); + + Assert1(GV, "Aliasee should be either GlobalValue, bitcast or " + "addrspacecast of GlobalValue", &GA); if (CE->getOpcode() == Instruction::BitCast) { - unsigned SrcAS = CE->getOperand(0)->getType()->getPointerAddressSpace(); + unsigned SrcAS = GV->getType()->getPointerAddressSpace(); unsigned DstAS = CE->getType()->getPointerAddressSpace(); Assert1(SrcAS == DstAS, @@ -565,15 +501,20 @@ void Verifier::visitGlobalAlias(GlobalAlias &GA) { &GA); } } + Assert1(!GV->isDeclaration(), "Alias must point to a definition", &GA); + if (const GlobalAlias *GAAliasee = dyn_cast(GV)) { + Assert1(!GAAliasee->mayBeOverridden(), "Alias cannot point to a weak alias", + &GA); + } - const GlobalValue* Resolved = GA.resolveAliasedGlobal(/*stopOnWeak*/ false); - Assert1(Resolved, - "Aliasing chain should end with function or global variable", &GA); + const GlobalValue *AG = GA.getAliasedGlobal(); + Assert1(AG, "Aliasing chain should end with function or global variable", + &GA); visitGlobalValue(GA); } -void Verifier::visitNamedMDNode(NamedMDNode &NMD) { +void Verifier::visitNamedMDNode(const NamedMDNode &NMD) { for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i) { MDNode *MD = NMD.getOperand(i); if (!MD) @@ -621,7 +562,7 @@ void Verifier::visitMDNode(MDNode &MD, Function *F) { } } -void Verifier::visitModuleIdents(Module &M) { +void Verifier::visitModuleIdents(const Module &M) { const NamedMDNode *Idents = M.getNamedMetadata("llvm.ident"); if (!Idents) return; @@ -639,24 +580,24 @@ void Verifier::visitModuleIdents(Module &M) { } } -void Verifier::visitModuleFlags(Module &M) { +void Verifier::visitModuleFlags(const Module &M) { const NamedMDNode *Flags = M.getModuleFlagsMetadata(); if (!Flags) return; // Scan each flag, and track the flags and requirements. - DenseMap SeenIDs; - SmallVector Requirements; + DenseMap SeenIDs; + SmallVector Requirements; for (unsigned I = 0, E = Flags->getNumOperands(); I != E; ++I) { visitModuleFlag(Flags->getOperand(I), SeenIDs, Requirements); } // Validate that the requirements in the module are valid. for (unsigned I = 0, E = Requirements.size(); I != E; ++I) { - MDNode *Requirement = Requirements[I]; - MDString *Flag = cast(Requirement->getOperand(0)); - Value *ReqValue = Requirement->getOperand(1); + const MDNode *Requirement = Requirements[I]; + const MDString *Flag = cast(Requirement->getOperand(0)); + const Value *ReqValue = Requirement->getOperand(1); - MDNode *Op = SeenIDs.lookup(Flag); + const MDNode *Op = SeenIDs.lookup(Flag); if (!Op) { CheckFailed("invalid requirement on flag, flag is not present in module", Flag); @@ -672,8 +613,10 @@ void Verifier::visitModuleFlags(Module &M) { } } -void Verifier::visitModuleFlag(MDNode *Op, DenseMap&SeenIDs, - SmallVectorImpl &Requirements) { +void +Verifier::visitModuleFlag(const MDNode *Op, + DenseMap &SeenIDs, + SmallVectorImpl &Requirements) { // Each module flag should have three arguments, the merge behavior (a // constant int), the flag ID (an MDString), and the value. Assert1(Op->getNumOperands() == 3, @@ -910,6 +853,11 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs, if (Attrs.hasAttribute(Idx, Attribute::StructRet)) Assert1(Idx == 1, "Attribute sret is not on first parameter!", V); + + if (Attrs.hasAttribute(Idx, Attribute::InAlloca)) { + Assert1(Idx == FT->getNumParams(), + "inalloca isn't on the last parameter!", V); + } } if (!Attrs.hasAttributes(AttributeSet::FunctionIndex)) @@ -1005,7 +953,7 @@ bool Verifier::VerifyAttributeCount(AttributeSet Attrs, unsigned Params) { // visitFunction - Verify that a function is ok. // -void Verifier::visitFunction(Function &F) { +void Verifier::visitFunction(const Function &F) { // Check function arguments. FunctionType *FT = F.getFunctionType(); unsigned NumArgs = F.arg_size(); @@ -1063,8 +1011,8 @@ void Verifier::visitFunction(Function &F) { // Check that the argument values match the function type for this function... unsigned i = 0; - for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); - I != E; ++I, ++i) { + for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; + ++I, ++i) { Assert2(I->getType() == FT->getParamType(i), "Argument value does not match function argument type!", I, FT->getParamType(i)); @@ -1078,8 +1026,7 @@ void Verifier::visitFunction(Function &F) { if (F.isMaterializable()) { // Function has a body somewhere we can't see. } else if (F.isDeclaration()) { - Assert1(F.hasExternalLinkage() || F.hasDLLImportLinkage() || - F.hasExternalWeakLinkage(), + Assert1(F.hasExternalLinkage() || F.hasExternalWeakLinkage(), "invalid linkage type for function declaration", &F); } else { // Verify that this function (which has a body) is not named "llvm.*". It @@ -1087,13 +1034,13 @@ void Verifier::visitFunction(Function &F) { Assert1(!isLLVMdotName, "llvm intrinsics cannot be defined!", &F); // Check the entry node - BasicBlock *Entry = &F.getEntryBlock(); + const BasicBlock *Entry = &F.getEntryBlock(); Assert1(pred_begin(Entry) == pred_end(Entry), "Entry block to function must not have predecessors!", Entry); // The address of the entry block cannot be taken, unless it is dead. if (Entry->hasAddressTaken()) { - Assert1(!BlockAddress::get(Entry)->isConstantUsed(), + Assert1(!BlockAddress::lookup(Entry)->isConstantUsed(), "blockaddress may not be used with the entry block!", Entry); } } @@ -1105,6 +1052,11 @@ void Verifier::visitFunction(Function &F) { if (F.hasAddressTaken(&U)) Assert1(0, "Invalid user of intrinsic instruction!", U); } + + Assert1(!F.hasDLLImportStorageClass() || + (F.isDeclaration() && F.hasExternalLinkage()) || + F.hasAvailableExternallyLinkage(), + "Function is marked as dllimport, but not external.", &F); } // verifyBasicBlock - Verify that a basic block is well formed... @@ -1537,15 +1489,6 @@ void Verifier::VerifyCallSite(CallSite CS) { // Verify call attributes. VerifyFunctionAttrs(FTy, Attrs, I); - // Verify that values used for inalloca parameters are in fact allocas. - for (unsigned i = 0, e = CS.arg_size(); i != e; ++i) { - if (!Attrs.hasAttribute(1 + i, Attribute::InAlloca)) - continue; - Value *Arg = CS.getArgument(i); - Assert2(isa(Arg), "Inalloca argument is not an alloca!", I, - Arg); - } - if (FTy->isVarArg()) { // FIXME? is 'nest' even legal here? bool SawNest = false; @@ -1579,6 +1522,10 @@ void Verifier::VerifyCallSite(CallSite CS) { Assert1(!Attrs.hasAttribute(Idx, Attribute::StructRet), "Attribute 'sret' cannot be used for vararg call arguments!", I); + + if (Attrs.hasAttribute(Idx, Attribute::InAlloca)) + Assert1(Idx == CS.arg_size(), "inalloca isn't on the last argument!", + I); } } @@ -1884,29 +1831,27 @@ void Verifier::visitAllocaInst(AllocaInst &AI) { Assert1(AI.getArraySize()->getType()->isIntegerTy(), "Alloca array size must have integer type", &AI); - // Verify that an alloca instruction is not used with inalloca more than once. - unsigned InAllocaUses = 0; - for (User::use_iterator UI = AI.use_begin(), UE = AI.use_end(); UI != UE; - ++UI) { - CallSite CS(*UI); - if (!CS) - continue; - unsigned ArgNo = CS.getArgumentNo(UI); - if (CS.isInAllocaArgument(ArgNo)) { - InAllocaUses++; - Assert1(InAllocaUses <= 1, - "Allocas can be used at most once with inalloca!", &AI); - } - } - visitInstruction(AI); } void Verifier::visitAtomicCmpXchgInst(AtomicCmpXchgInst &CXI) { - Assert1(CXI.getOrdering() != NotAtomic, + + // FIXME: more conditions??? + Assert1(CXI.getSuccessOrdering() != NotAtomic, "cmpxchg instructions must be atomic.", &CXI); - Assert1(CXI.getOrdering() != Unordered, + Assert1(CXI.getFailureOrdering() != NotAtomic, + "cmpxchg instructions must be atomic.", &CXI); + Assert1(CXI.getSuccessOrdering() != Unordered, + "cmpxchg instructions cannot be unordered.", &CXI); + Assert1(CXI.getFailureOrdering() != Unordered, "cmpxchg instructions cannot be unordered.", &CXI); + Assert1(CXI.getSuccessOrdering() >= CXI.getFailureOrdering(), + "cmpxchg instructions be at least as constrained on success as fail", + &CXI); + Assert1(CXI.getFailureOrdering() != Release && + CXI.getFailureOrdering() != AcquireRelease, + "cmpxchg failure ordering cannot include release semantics", &CXI); + PointerType *PTy = dyn_cast(CXI.getOperand(0)->getType()); Assert1(PTy, "First cmpxchg operand must be a pointer.", &CXI); Type *ElTy = PTy->getElementType(); @@ -2037,7 +1982,7 @@ void Verifier::verifyDominatesUse(Instruction &I, unsigned i) { } const Use &U = I.getOperandUse(i); - Assert2(InstsInThisBlock.count(Op) || DT->dominates(Op, U), + Assert2(InstsInThisBlock.count(Op) || DT.dominates(Op, U), "Instruction does not dominate all uses!", Op, &I); } @@ -2048,10 +1993,10 @@ void Verifier::visitInstruction(Instruction &I) { Assert1(BB, "Instruction not embedded in basic block!", &I); if (!isa(I)) { // Check that non-phi nodes are not self referential - for (Value::use_iterator UI = I.use_begin(), UE = I.use_end(); - UI != UE; ++UI) - Assert1(*UI != (User*)&I || !DT->isReachableFromEntry(BB), + for (User *U : I.users()) { + Assert1(U != (User*)&I || !DT.isReachableFromEntry(BB), "Only PHI nodes may reference their own value!", &I); + } } // Check that void typed values don't have names @@ -2073,13 +2018,12 @@ void Verifier::visitInstruction(Instruction &I) { // Check that all uses of the instruction, if they are instructions // themselves, actually have parent basic blocks. If the use is not an // instruction, it is an error! - for (User::use_iterator UI = I.use_begin(), UE = I.use_end(); - UI != UE; ++UI) { - if (Instruction *Used = dyn_cast(*UI)) + for (Use &U : I.uses()) { + if (Instruction *Used = dyn_cast(U.getUser())) Assert2(Used->getParent() != 0, "Instruction referencing instruction not" " embedded in a basic block!", &I, Used); else { - CheckFailed("Use of instruction is not an instruction!", *UI); + CheckFailed("Use of instruction is not an instruction!", U); return; } } @@ -2101,7 +2045,7 @@ void Verifier::visitInstruction(Instruction &I) { Assert1(!F->isIntrinsic() || isa(I) || F->getIntrinsicID() == Intrinsic::donothing, "Cannot invoke an intrinsinc other than donothing", &I); - Assert1(F->getParent() == Mod, "Referencing function in another module!", + Assert1(F->getParent() == M, "Referencing function in another module!", &I); } else if (BasicBlock *OpBB = dyn_cast(I.getOperand(i))) { Assert1(OpBB->getParent() == BB->getParent(), @@ -2110,7 +2054,7 @@ void Verifier::visitInstruction(Instruction &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!", + Assert1(GV->getParent() == M, "Referencing global in another module!", &I); } else if (isa(I.getOperand(i))) { verifyDominatesUse(I, i); @@ -2161,7 +2105,7 @@ void Verifier::visitInstruction(Instruction &I) { if (!DisableDebugInfoVerifier) { MD = I.getMetadata(LLVMContext::MD_dbg); - Finder.processLocation(*Mod, DILocation(MD)); + Finder.processLocation(*M, DILocation(MD)); } InstsInThisBlock.insert(&I); @@ -2232,18 +2176,41 @@ bool Verifier::VerifyIntrinsicType(Type *Ty, } llvm_unreachable("all argument kinds not covered"); - case IITDescriptor::ExtendVecArgument: + case IITDescriptor::ExtendArgument: { // This may only be used when referring to a previous vector argument. - return D.getArgumentNumber() >= ArgTys.size() || - !isa(ArgTys[D.getArgumentNumber()]) || - VectorType::getExtendedElementVectorType( - cast(ArgTys[D.getArgumentNumber()])) != Ty; + if (D.getArgumentNumber() >= ArgTys.size()) + return true; + + Type *NewTy = ArgTys[D.getArgumentNumber()]; + if (VectorType *VTy = dyn_cast(NewTy)) + NewTy = VectorType::getExtendedElementVectorType(VTy); + else if (IntegerType *ITy = dyn_cast(NewTy)) + NewTy = IntegerType::get(ITy->getContext(), 2 * ITy->getBitWidth()); + else + return true; + + return Ty != NewTy; + } + case IITDescriptor::TruncArgument: { + // This may only be used when referring to a previous vector argument. + if (D.getArgumentNumber() >= ArgTys.size()) + return true; - case IITDescriptor::TruncVecArgument: + Type *NewTy = ArgTys[D.getArgumentNumber()]; + if (VectorType *VTy = dyn_cast(NewTy)) + NewTy = VectorType::getTruncatedElementVectorType(VTy); + else if (IntegerType *ITy = dyn_cast(NewTy)) + NewTy = IntegerType::get(ITy->getContext(), ITy->getBitWidth() / 2); + else + return true; + + return Ty != NewTy; + } + case IITDescriptor::HalfVecArgument: // This may only be used when referring to a previous vector argument. return D.getArgumentNumber() >= ArgTys.size() || !isa(ArgTys[D.getArgumentNumber()]) || - VectorType::getTruncatedElementVectorType( + VectorType::getHalfElementsVectorType( cast(ArgTys[D.getArgumentNumber()])) != Ty; } llvm_unreachable("unhandled"); @@ -2314,8 +2281,10 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { // know they are legal for the intrinsic!) get the intrinsic name through the // usual means. This allows us to verify the mangling of argument types into // the name. - Assert1(Intrinsic::getName(ID, ArgTys) == IF->getName(), - "Intrinsic name not mangled correctly for type arguments!", IF); + const std::string ExpectedName = Intrinsic::getName(ID, ArgTys); + Assert1(ExpectedName == IF->getName(), + "Intrinsic name not mangled correctly for type arguments! " + "Should be: " + ExpectedName, IF); // If the intrinsic takes MDNode arguments, verify that they are either global // or are local to *this* function. @@ -2339,13 +2308,13 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { Assert1(MD->getNumOperands() == 1, "invalid llvm.dbg.declare intrinsic call 2", &CI); if (!DisableDebugInfoVerifier) - Finder.processDeclare(*Mod, cast(&CI)); + Finder.processDeclare(*M, cast(&CI)); } break; case Intrinsic::dbg_value: { //llvm.dbg.value if (!DisableDebugInfoVerifier) { Assert1(CI.getArgOperand(0) && isa(CI.getArgOperand(0)), "invalid llvm.dbg.value intrinsic call 1", &CI); - Finder.processValue(*Mod, cast(&CI)); + Finder.processValue(*M, cast(&CI)); } break; } @@ -2413,22 +2382,21 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { void Verifier::verifyDebugInfo() { // Verify Debug Info. if (!DisableDebugInfoVerifier) { - for (DebugInfoFinder::iterator I = Finder.compile_unit_begin(), - E = Finder.compile_unit_end(); I != E; ++I) - Assert1(DICompileUnit(*I).Verify(), "DICompileUnit does not Verify!", *I); - for (DebugInfoFinder::iterator I = Finder.subprogram_begin(), - E = Finder.subprogram_end(); I != E; ++I) - Assert1(DISubprogram(*I).Verify(), "DISubprogram does not Verify!", *I); - for (DebugInfoFinder::iterator I = Finder.global_variable_begin(), - E = Finder.global_variable_end(); I != E; ++I) - Assert1(DIGlobalVariable(*I).Verify(), - "DIGlobalVariable does not Verify!", *I); - for (DebugInfoFinder::iterator I = Finder.type_begin(), - E = Finder.type_end(); I != E; ++I) - Assert1(DIType(*I).Verify(), "DIType does not Verify!", *I); - for (DebugInfoFinder::iterator I = Finder.scope_begin(), - E = Finder.scope_end(); I != E; ++I) - Assert1(DIScope(*I).Verify(), "DIScope does not Verify!", *I); + for (DICompileUnit CU : Finder.compile_units()) { + Assert1(CU.Verify(), "DICompileUnit does not Verify!", CU); + } + for (DISubprogram S : Finder.subprograms()) { + Assert1(S.Verify(), "DISubprogram does not Verify!", S); + } + for (DIGlobalVariable GV : Finder.global_variables()) { + Assert1(GV.Verify(), "DIGlobalVariable does not Verify!", GV); + } + for (DIType T : Finder.types()) { + Assert1(T.Verify(), "DIType does not Verify!", T); + } + for (DIScope S : Finder.scopes()) { + Assert1(S.Verify(), "DIScope does not Verify!", S); + } } } @@ -2436,37 +2404,84 @@ void Verifier::verifyDebugInfo() { // Implement the public interfaces to this file... //===----------------------------------------------------------------------===// -FunctionPass *llvm::createVerifierPass(VerifierFailureAction action) { - return new Verifier(action); +bool llvm::verifyFunction(const Function &f, raw_ostream *OS) { + Function &F = const_cast(f); + assert(!F.isDeclaration() && "Cannot verify external functions"); + + raw_null_ostream NullStr; + Verifier V(OS ? *OS : NullStr); + + // Note that this function's return value is inverted from what you would + // expect of a function called "verify". + return !V.verify(F); } +bool llvm::verifyModule(const Module &M, raw_ostream *OS) { + raw_null_ostream NullStr; + Verifier V(OS ? *OS : NullStr); -/// verifyFunction - Check a function for errors, printing messages on stderr. -/// Return true if the function is corrupt. -/// -bool llvm::verifyFunction(const Function &f, VerifierFailureAction action) { - Function &F = const_cast(f); - assert(!F.isDeclaration() && "Cannot verify external functions"); + bool Broken = false; + for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) + if (!I->isDeclaration()) + Broken |= !V.verify(*I); - FunctionPassManager FPM(F.getParent()); - Verifier *V = new Verifier(action); - FPM.add(V); - FPM.doInitialization(); - FPM.run(F); - return V->Broken; + // Note that this function's return value is inverted from what you would + // expect of a function called "verify". + return !V.verify(M) || Broken; } -/// verifyModule - Check a module for errors, printing messages on stderr. -/// Return true if the module is corrupt. -/// -bool llvm::verifyModule(const Module &M, VerifierFailureAction action, - std::string *ErrorInfo) { - PassManager PM; - Verifier *V = new Verifier(action); - PM.add(V); - PM.run(const_cast(M)); - - if (ErrorInfo && V->Broken) - *ErrorInfo = V->MessagesStr.str(); - return V->Broken; +namespace { +struct VerifierLegacyPass : public FunctionPass { + static char ID; + + Verifier V; + bool FatalErrors; + + VerifierLegacyPass() : FunctionPass(ID), FatalErrors(true) { + initializeVerifierLegacyPassPass(*PassRegistry::getPassRegistry()); + } + explicit VerifierLegacyPass(bool FatalErrors) + : FunctionPass(ID), V(dbgs()), FatalErrors(FatalErrors) { + initializeVerifierLegacyPassPass(*PassRegistry::getPassRegistry()); + } + + bool runOnFunction(Function &F) override { + if (!V.verify(F) && FatalErrors) + report_fatal_error("Broken function found, compilation aborted!"); + + return false; + } + + bool doFinalization(Module &M) override { + if (!V.verify(M) && FatalErrors) + report_fatal_error("Broken module found, compilation aborted!"); + + return false; + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } +}; +} + +char VerifierLegacyPass::ID = 0; +INITIALIZE_PASS(VerifierLegacyPass, "verify", "Module Verifier", false, false) + +FunctionPass *llvm::createVerifierPass(bool FatalErrors) { + return new VerifierLegacyPass(FatalErrors); +} + +PreservedAnalyses VerifierPass::run(Module *M) { + if (verifyModule(*M, &dbgs()) && FatalErrors) + report_fatal_error("Broken module found, compilation aborted!"); + + return PreservedAnalyses::all(); +} + +PreservedAnalyses VerifierPass::run(Function *F) { + if (verifyFunction(*F, &dbgs()) && FatalErrors) + report_fatal_error("Broken function found, compilation aborted!"); + + return PreservedAnalyses::all(); }