#include "llvm/Analysis/Dominators.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/InstVisitor.h"
+#include "llvm/Support/Streams.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Compiler.h"
#include <algorithm>
-#include <iostream>
-#include <sstream>
#include <cstdarg>
using namespace llvm;
namespace { // Anonymous namespace for class
- struct Verifier : public FunctionPass, InstVisitor<Verifier> {
+ struct VISIBILITY_HIDDEN
+ Verifier : public FunctionPass, InstVisitor<Verifier> {
bool Broken; // Is this module found to be broken?
bool RealPass; // Are we not being run by a PassManager?
VerifierFailureAction action;
// returning back to the pass manager, or else the pass manager may try to
// run other passes on the broken module.
if (RealPass)
- abortIfBroken();
+ return abortIfBroken();
return false;
}
// returning back to the pass manager, or else the pass manager may try to
// run other passes on the broken module.
if (RealPass)
- abortIfBroken();
+ return abortIfBroken();
return false;
}
visitGlobalVariable(*I);
// If the module is broken, abort at this time.
- abortIfBroken();
- return false;
+ return abortIfBroken();
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
/// abortIfBroken - If the module is broken and we are supposed to abort on
/// this condition, do so.
///
- void abortIfBroken() {
- if (Broken)
- {
+ bool abortIfBroken() {
+ if (Broken) {
msgs << "Broken module found, ";
- switch (action)
- {
+ switch (action) {
case AbortProcessAction:
msgs << "compilation aborted!\n";
- std::cerr << msgs.str();
+ cerr << msgs.str();
abort();
- case ThrowExceptionAction:
- msgs << "verification terminated.\n";
- throw msgs.str();
case PrintMessageAction:
msgs << "verification continues.\n";
- std::cerr << msgs.str();
- break;
+ cerr << msgs.str();
+ return false;
case ReturnStatusAction:
- break;
+ msgs << "compilation terminated.\n";
+ return Broken;
}
}
+ return false;
}
void visitGlobalVariable(GlobalVariable &GV);
void visitFunction(Function &F);
void visitBasicBlock(BasicBlock &BB);
+ 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 visitPHINode(PHINode &PN);
void visitBinaryOperator(BinaryOperator &B);
+ void visitICmpInst(ICmpInst &IC);
+ void visitFCmpInst(FCmpInst &FC);
void visitShiftInst(ShiftInst &SI);
void visitExtractElementInst(ExtractElementInst &EI);
void visitInsertElementInst(InsertElementInst &EI);
if (isa<Instruction>(V)) {
msgs << *V;
} else {
- WriteAsOperand (msgs, V, true, true, Mod);
+ WriteAsOperand(msgs, V, true, Mod);
msgs << "\n";
}
}
}
};
- RegisterOpt<Verifier> X("verify", "Module Verifier");
+ RegisterPass<Verifier> X("verify", "Module Verifier");
} // End anonymous namespace
void Verifier::visitGlobalValue(GlobalValue &GV) {
- Assert1(!GV.isExternal() || GV.hasExternalLinkage(),
- "Global is external, but doesn't have external linkage!", &GV);
+ Assert1(!GV.isExternal() ||
+ GV.hasExternalLinkage() ||
+ GV.hasDLLImportLinkage() ||
+ GV.hasExternalWeakLinkage(),
+ "Global is external, but doesn't have external or dllimport or weak linkage!",
+ &GV);
+
+ Assert1(!GV.hasDLLImportLinkage() || GV.isExternal(),
+ "Global is marked as dllimport, but not external", &GV);
+
Assert1(!GV.hasAppendingLinkage() || isa<GlobalVariable>(GV),
"Only global variables can have appending linkage!", &GV);
break;
case CallingConv::Fast:
case CallingConv::Cold:
+ case CallingConv::X86_FastCall:
Assert1(!F.isVarArg(),
"Varargs functions must have C calling conventions!", &F);
break;
Assert1(0, "User-defined operators should not live outside of a pass!", &I);
}
+void Verifier::visitTruncInst(TruncInst &I) {
+ // Get the source and destination types
+ const Type *SrcTy = I.getOperand(0)->getType();
+ const Type *DestTy = I.getType();
+
+ // Get the size of the types in bits, we'll need this later
+ unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
+ unsigned DestBitSize = DestTy->getPrimitiveSizeInBits();
+
+ Assert1(SrcTy->isIntegral(), "Trunc only operates on integer", &I);
+ Assert1(DestTy->isIntegral(),"Trunc only produces integral", &I);
+ Assert1(SrcBitSize > DestBitSize,"DestTy too big for Trunc", &I);
+
+ visitInstruction(I);
+}
+
+void Verifier::visitZExtInst(ZExtInst &I) {
+ // Get the source and destination types
+ const Type *SrcTy = I.getOperand(0)->getType();
+ const Type *DestTy = I.getType();
+
+ // Get the size of the types in bits, we'll need this later
+ unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
+ unsigned DestBitSize = DestTy->getPrimitiveSizeInBits();
+
+ Assert1(SrcTy->isIntegral(),"ZExt only operates on integral", &I);
+ Assert1(DestTy->isInteger(),"ZExt only produces an integer", &I);
+ Assert1(SrcBitSize < DestBitSize,"Type too small for ZExt", &I);
+
+ visitInstruction(I);
+}
+
+void Verifier::visitSExtInst(SExtInst &I) {
+ // Get the source and destination types
+ const Type *SrcTy = I.getOperand(0)->getType();
+ const Type *DestTy = I.getType();
+
+ // Get the size of the types in bits, we'll need this later
+ unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
+ unsigned DestBitSize = DestTy->getPrimitiveSizeInBits();
+
+ Assert1(SrcTy->isIntegral(),"SExt only operates on integral", &I);
+ Assert1(DestTy->isInteger(),"SExt only produces an integer", &I);
+ Assert1(SrcBitSize < DestBitSize,"Type too small for SExt", &I);
+
+ visitInstruction(I);
+}
+
+void Verifier::visitFPTruncInst(FPTruncInst &I) {
+ // Get the source and destination types
+ const Type *SrcTy = I.getOperand(0)->getType();
+ const Type *DestTy = I.getType();
+ // Get the size of the types in bits, we'll need this later
+ unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
+ unsigned DestBitSize = DestTy->getPrimitiveSizeInBits();
+
+ Assert1(SrcTy->isFloatingPoint(),"FPTrunc only operates on FP", &I);
+ Assert1(DestTy->isFloatingPoint(),"FPTrunc only produces an FP", &I);
+ Assert1(SrcBitSize > DestBitSize,"DestTy too big for FPTrunc", &I);
+
+ visitInstruction(I);
+}
+
+void Verifier::visitFPExtInst(FPExtInst &I) {
+ // Get the source and destination types
+ const Type *SrcTy = I.getOperand(0)->getType();
+ const Type *DestTy = I.getType();
+
+ // Get the size of the types in bits, we'll need this later
+ unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
+ unsigned DestBitSize = DestTy->getPrimitiveSizeInBits();
+
+ Assert1(SrcTy->isFloatingPoint(),"FPExt only operates on FP", &I);
+ Assert1(DestTy->isFloatingPoint(),"FPExt only produces an FP", &I);
+ Assert1(SrcBitSize < DestBitSize,"DestTy too small for FPExt", &I);
+
+ visitInstruction(I);
+}
+
+void Verifier::visitUIToFPInst(UIToFPInst &I) {
+ // Get the source and destination types
+ const Type *SrcTy = I.getOperand(0)->getType();
+ const Type *DestTy = I.getType();
+
+ Assert1(SrcTy->isIntegral(),"UInt2FP source must be integral", &I);
+ Assert1(DestTy->isFloatingPoint(),"UInt2FP result must be FP", &I);
+
+ visitInstruction(I);
+}
+
+void Verifier::visitSIToFPInst(SIToFPInst &I) {
+ // Get the source and destination types
+ const Type *SrcTy = I.getOperand(0)->getType();
+ const Type *DestTy = I.getType();
+
+ Assert1(SrcTy->isIntegral(),"SInt2FP source must be integral", &I);
+ Assert1(DestTy->isFloatingPoint(),"SInt2FP result must be FP", &I);
+
+ visitInstruction(I);
+}
+
+void Verifier::visitFPToUIInst(FPToUIInst &I) {
+ // Get the source and destination types
+ const Type *SrcTy = I.getOperand(0)->getType();
+ const Type *DestTy = I.getType();
+
+ Assert1(SrcTy->isFloatingPoint(),"FP2UInt source must be FP", &I);
+ Assert1(DestTy->isIntegral(),"FP2UInt result must be integral", &I);
+
+ visitInstruction(I);
+}
+
+void Verifier::visitFPToSIInst(FPToSIInst &I) {
+ // Get the source and destination types
+ const Type *SrcTy = I.getOperand(0)->getType();
+ const Type *DestTy = I.getType();
+
+ Assert1(SrcTy->isFloatingPoint(),"FPToSI source must be FP", &I);
+ Assert1(DestTy->isIntegral(),"FP2ToI result must be integral", &I);
+
+ visitInstruction(I);
+}
+
+void Verifier::visitPtrToIntInst(PtrToIntInst &I) {
+ // Get the source and destination types
+ const Type *SrcTy = I.getOperand(0)->getType();
+ const Type *DestTy = I.getType();
+
+ Assert1(isa<PointerType>(SrcTy), "PtrToInt source must be pointer", &I);
+ Assert1(DestTy->isIntegral(), "PtrToInt result must be integral", &I);
+
+ visitInstruction(I);
+}
+
+void Verifier::visitIntToPtrInst(IntToPtrInst &I) {
+ // Get the source and destination types
+ const Type *SrcTy = I.getOperand(0)->getType();
+ const Type *DestTy = I.getType();
+
+ Assert1(SrcTy->isIntegral(), "IntToPtr source must be an integral", &I);
+ Assert1(isa<PointerType>(DestTy), "IntToPtr result must be a pointer",&I);
+
+ visitInstruction(I);
+}
+
+void Verifier::visitBitCastInst(BitCastInst &I) {
+ // Get the source and destination types
+ const Type *SrcTy = I.getOperand(0)->getType();
+ const Type *DestTy = I.getType();
+
+ // Get the size of the types in bits, we'll need this later
+ unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
+ unsigned DestBitSize = DestTy->getPrimitiveSizeInBits();
+
+ // BitCast implies a no-op cast of type only. No bits change.
+ // However, you can't cast pointers to anything but pointers.
+ Assert1(isa<PointerType>(DestTy) == isa<PointerType>(DestTy),
+ "Bitcast requires both operands to be pointer or neither", &I);
+ Assert1(SrcBitSize == DestBitSize, "Bitcast requies types of same width", &I);
+
+ visitInstruction(I);
+}
+
/// visitPHINode - Ensure that a PHI node is well formed.
///
void Verifier::visitPHINode(PHINode &PN) {
visitInstruction(B);
}
+void Verifier::visitICmpInst(ICmpInst& IC) {
+ // Check that the operands are the same type
+ const Type* Op0Ty = IC.getOperand(0)->getType();
+ const Type* Op1Ty = IC.getOperand(1)->getType();
+ Assert1(Op0Ty == Op1Ty,
+ "Both operands to ICmp instruction are not of the same type!", &IC);
+ // Check that the operands are the right type
+ Assert1(Op0Ty->isIntegral() || Op0Ty->getTypeID() == Type::PointerTyID ||
+ (isa<PackedType>(Op0Ty) &&
+ cast<PackedType>(Op0Ty)->getElementType()->isIntegral()),
+ "Invalid operand types for ICmp instruction", &IC);
+ visitInstruction(IC);
+}
+
+void Verifier::visitFCmpInst(FCmpInst& FC) {
+ // Check that the operands are the same type
+ const Type* Op0Ty = FC.getOperand(0)->getType();
+ const Type* Op1Ty = FC.getOperand(1)->getType();
+ Assert1(Op0Ty == Op1Ty,
+ "Both operands to FCmp instruction are not of the same type!", &FC);
+ // Check that the operands are the right type
+ Assert1(Op0Ty->isFloatingPoint() || (isa<PackedType>(Op0Ty) &&
+ cast<PackedType>(Op0Ty)->getElementType()->isFloatingPoint()),
+ "Invalid operand types for FCmp instruction", &FC);
+ visitInstruction(FC);
+}
+
void Verifier::visitShiftInst(ShiftInst &SI) {
Assert1(SI.getType()->isInteger(),
"Shift must return an integer result!", &SI);
// Check to see if Mask is valid.
if (const ConstantPacked *MV = dyn_cast<ConstantPacked>(SV.getOperand(2))) {
for (unsigned i = 0, e = MV->getNumOperands(); i != e; ++i) {
- Assert1(isa<ConstantUInt>(MV->getOperand(i)) ||
+ Assert1(isa<ConstantInt>(MV->getOperand(i)) ||
isa<UndefValue>(MV->getOperand(i)),
"Invalid shufflevector shuffle mask!", &SV);
}
}
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
- // Check to make sure that the "address of" an intrinsic function is never
- // taken.
Assert1(I.getOperand(i) != 0, "Instruction has null operand!", &I);
+
+ // Check to make sure that only first-class-values are operands to
+ // instructions.
+ Assert1(I.getOperand(i)->getType()->isFirstClassType(),
+ "Instruction operands must be first-class values!", &I);
+
if (Function *F = dyn_cast<Function>(I.getOperand(i))) {
+ // Check to make sure that the "address of" an intrinsic function is never
+ // taken.
Assert1(!F->isIntrinsic() || (i == 0 && isa<CallInst>(I)),
"Cannot take the address of an intrinsic!", &I);
} else if (BasicBlock *OpBB = dyn_cast<BasicBlock>(I.getOperand(i))) {
/// 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) {
+bool llvm::verifyModule(const Module &M, VerifierFailureAction action,
+ std::string *ErrorInfo) {
PassManager PM;
Verifier *V = new Verifier(action);
PM.add(V);
PM.run((Module&)M);
+
+ if (ErrorInfo && V->Broken)
+ *ErrorInfo = V->msgs.str();
return V->Broken;
}