#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/DerivedTypes.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/InstVisitor.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"
static cl::opt<bool> 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<Verifier> {
- 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<Instruction*, 16> InstsInThisBlock;
-
- /// MDNodes - keep track of the metadata nodes that have been checked
- /// already.
- SmallPtrSet<MDNode *, 32> 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<Verifier> {
+ friend class InstVisitor<Verifier>;
+
+ 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<Instruction *, 16> InstsInThisBlock;
+
+ /// \brief Keep track of the metadata nodes that have been checked already.
+ SmallPtrSet<MDNode *, 32> 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<Function &>(F));
- DL = getAnalysisIfAvailable<DataLayout>();
+ Finder.reset();
+ Broken = false;
+ // FIXME: We strip const here because the inst visitor strips const.
+ visit(const_cast<Function &>(F));
+ InstsInThisBlock.clear();
+ PersonalityFn = 0;
- // 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();
- }
-
- bool runOnFunction(Function &F) {
- // Get dominator information if we are being run by PassManager
- DT = &getAnalysis<DominatorTreeWrapperPass>().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);
+ for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
+ I != E; ++I)
+ visitGlobalVariable(*I);
- // Check to make sure function prototypes are okay.
- if (I->isDeclaration()) visitFunction(*I);
- }
+ for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
+ I != E; ++I)
+ visitGlobalAlias(*I);
- for (Module::global_iterator I = M.global_begin(), E = M.global_end();
- I != E; ++I)
- visitGlobalVariable(*I);
+ for (Module::const_named_metadata_iterator I = M.named_metadata_begin(),
+ E = M.named_metadata_end();
+ I != E; ++I)
+ visitNamedMDNode(*I);
- for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
- I != E; ++I)
- visitGlobalAlias(*I);
+ visitModuleFlags(M);
+ visitModuleIdents(M);
- for (Module::named_metadata_iterator I = M.named_metadata_begin(),
- E = M.named_metadata_end(); I != E; ++I)
- visitNamedMDNode(*I);
-
- visitModuleFlags(M);
- visitModuleIdents(M);
-
- if (!DisableDebugInfoVerifier) {
- Finder.reset();
- Finder.processModule(M);
- // Verify Debug Info.
- verifyDebugInfo();
- }
-
- // If the module is broken, abort at this time.
- return abortIfBroken();
- }
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- AU.addRequiredID(PreVerifyID);
- AU.addRequired<DominatorTreeWrapperPass>();
- }
-
- /// 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<MDString*, MDNode*> &SeenIDs,
- SmallVectorImpl<MDNode*> &Requirements);
- void visitFunction(Function &F);
- void visitBasicBlock(BasicBlock &BB);
- using InstVisitor<Verifier>::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<Intrinsic::IITDescriptor> &Infos,
- SmallVectorImpl<Type*> &ArgTys);
- bool VerifyIntrinsicIsVarArg(bool isVarArg,
- ArrayRef<Intrinsic::IITDescriptor> &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<Instruction>(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<const MDString *, const MDNode *> &SeenIDs,
+ SmallVectorImpl<const MDNode *> &Requirements);
+ void visitFunction(const Function &F);
+ void visitBasicBlock(BasicBlock &BB);
+
+ // InstVisitor overrides...
+ using InstVisitor<Verifier>::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<Intrinsic::IITDescriptor> &Infos,
+ SmallVectorImpl<Type *> &ArgTys);
+ bool VerifyIntrinsicIsVarArg(bool isVarArg,
+ ArrayRef<Intrinsic::IITDescriptor> &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<Instruction>(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)
}
-void Verifier::visitGlobalValue(GlobalValue &GV) {
+void Verifier::visitGlobalValue(const GlobalValue &GV) {
Assert1(!GV.isDeclaration() ||
GV.isMaterializable() ||
GV.hasExternalLinkage() ||
"Only global variables can have appending linkage!", &GV);
if (GV.hasAppendingLinkage()) {
- GlobalVariable *GVar = dyn_cast<GlobalVariable>(&GV);
+ const GlobalVariable *GVar = dyn_cast<GlobalVariable>(&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 "
PointerType *PTy = dyn_cast<PointerType>(ATy->getElementType());
Assert1(PTy, "wrong type for intrinsic global variable", &GV);
if (GV.hasInitializer()) {
- Constant *Init = GV.getInitializer();
- ConstantArray *InitArray = dyn_cast<ConstantArray>(Init);
+ const Constant *Init = GV.getInitializer();
+ const ConstantArray *InitArray = dyn_cast<ConstantArray>(Init);
Assert1(InitArray, "wrong initalizer for intrinsic global variable",
Init);
for (unsigned i = 0, e = InitArray->getNumOperands(); i != e; ++i) {
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()),
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);
- Constant *Aliasee = GA.getAliasee();
+ const Constant *Aliasee = GA.getAliasee();
if (!isa<GlobalValue>(Aliasee)) {
- ConstantExpr *CE = dyn_cast<ConstantExpr>(Aliasee);
+ const ConstantExpr *CE = dyn_cast<ConstantExpr>(Aliasee);
Assert1(CE &&
(CE->getOpcode() == Instruction::BitCast ||
CE->getOpcode() == Instruction::AddrSpaceCast ||
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)
}
}
-void Verifier::visitModuleIdents(Module &M) {
+void Verifier::visitModuleIdents(const Module &M) {
const NamedMDNode *Idents = M.getNamedMetadata("llvm.ident");
if (!Idents)
return;
}
}
-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<MDString*, MDNode*> SeenIDs;
- SmallVector<MDNode*, 16> Requirements;
+ DenseMap<const MDString*, const MDNode*> SeenIDs;
+ SmallVector<const MDNode*, 16> 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<MDString>(Requirement->getOperand(0));
- Value *ReqValue = Requirement->getOperand(1);
+ const MDNode *Requirement = Requirements[I];
+ const MDString *Flag = cast<MDString>(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);
}
}
-void Verifier::visitModuleFlag(MDNode *Op, DenseMap<MDString*, MDNode*>&SeenIDs,
- SmallVectorImpl<MDNode*> &Requirements) {
+void
+Verifier::visitModuleFlag(const MDNode *Op,
+ DenseMap<const MDString *, const MDNode *> &SeenIDs,
+ SmallVectorImpl<const MDNode *> &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,
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))
// 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();
// 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));
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);
}
}
// 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<AllocaInst>(Arg), "Inalloca argument is not an alloca!", I,
- Arg);
- }
-
if (FTy->isVarArg()) {
// FIXME? is 'nest' even legal here?
bool SawNest = false;
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);
}
}
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);
}
}
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);
}
if (!isa<PHINode>(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),
+ Assert1(*UI != (User*)&I || !DT.isReachableFromEntry(BB),
"Only PHI nodes may reference their own value!", &I);
}
Assert1(!F->isIntrinsic() || isa<CallInst>(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<BasicBlock>(I.getOperand(i))) {
Assert1(OpBB->getParent() == BB->getParent(),
Assert1(OpArg->getParent() == BB->getParent(),
"Referring to an argument in another function!", &I);
} else if (GlobalValue *GV = dyn_cast<GlobalValue>(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<Instruction>(I.getOperand(i))) {
verifyDominatesUse(I, i);
if (!DisableDebugInfoVerifier) {
MD = I.getMetadata(LLVMContext::MD_dbg);
- Finder.processLocation(*Mod, DILocation(MD));
+ Finder.processLocation(*M, DILocation(MD));
}
InstsInThisBlock.insert(&I);
Assert1(MD->getNumOperands() == 1,
"invalid llvm.dbg.declare intrinsic call 2", &CI);
if (!DisableDebugInfoVerifier)
- Finder.processDeclare(*Mod, cast<DbgDeclareInst>(&CI));
+ Finder.processDeclare(*M, cast<DbgDeclareInst>(&CI));
} break;
case Intrinsic::dbg_value: { //llvm.dbg.value
if (!DisableDebugInfoVerifier) {
Assert1(CI.getArgOperand(0) && isa<MDNode>(CI.getArgOperand(0)),
"invalid llvm.dbg.value intrinsic call 1", &CI);
- Finder.processValue(*Mod, cast<DbgValueInst>(&CI));
+ Finder.processValue(*M, cast<DbgValueInst>(&CI));
}
break;
}
// 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<Function &>(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<Function&>(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<Module&>(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) {
+ if (!V.verify(F) && FatalErrors)
+ report_fatal_error("Broken function found, compilation aborted!");
+
+ return false;
+ }
+
+ bool doFinalization(Module &M) {
+ if (!V.verify(M) && FatalErrors)
+ report_fatal_error("Broken module found, compilation aborted!");
+
+ return false;
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ 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();
}