#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/CFG.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/InstVisitor.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
using namespace llvm;
namespace { // Anonymous namespace for class
- struct VISIBILITY_HIDDEN PreVerifier : public FunctionPass {
+ struct PreVerifier : public FunctionPass {
static char ID; // Pass ID, replacement for typeid
PreVerifier() : FunctionPass(&ID) { }
for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
if (I->empty() || !I->back().isTerminator()) {
- errs() << "Basic Block does not have terminator!\n";
- WriteAsOperand(errs(), I, true);
- errs() << "\n";
+ dbgs() << "Basic Block does not have terminator!\n";
+ WriteAsOperand(dbgs(), I, true);
+ dbgs() << "\n";
Broken = true;
}
}
static const PassInfo *const PreVerifyID = &PreVer;
namespace {
- struct TypeSet : public AbstractTypeUser {
- SmallSetVector<const Type *, 16> Types;
+ class TypeSet : public AbstractTypeUser {
+ public:
+ TypeSet() {}
/// Insert a type into the set of types.
bool insert(const Type *Ty) {
Types.remove(OldTy);
OldTy->removeAbstractTypeUser(this);
}
- void typeBecameConcrete(const DerivedType *AbsTy) {}
+
+ /// Stop listening for changes to a type which is no longer abstract.
+ void typeBecameConcrete(const DerivedType *AbsTy) {
+ AbsTy->removeAbstractTypeUser(this);
+ }
+
void dump() const {}
+
+ private:
+ SmallSetVector<const Type *, 16> Types;
+
+ // Disallow copying.
+ TypeSet(const TypeSet &);
+ TypeSet &operator=(const TypeSet &);
};
struct Verifier : public FunctionPass, public InstVisitor<Verifier> {
default: llvm_unreachable("Unknown action");
case AbortProcessAction:
MessagesStr << "compilation aborted!\n";
- errs() << MessagesStr.str();
+ dbgs() << MessagesStr.str();
// Client should choose different reaction if abort is not desired
abort();
case PrintMessageAction:
MessagesStr << "verification continues.\n";
- errs() << MessagesStr.str();
+ dbgs() << MessagesStr.str();
return false;
case ReturnStatusAction:
MessagesStr << "compilation terminated.\n";
void visitUserOp1(Instruction &I);
void visitUserOp2(Instruction &I) { visitUserOp1(I); }
void visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI);
- void visitAllocationInst(AllocationInst &AI);
+ void visitAllocaInst(AllocaInst &AI);
void visitExtractValueInst(ExtractValueInst &EVI);
void visitInsertValueInst(InsertValueInst &IVI);
int VT, unsigned ArgNo, std::string &Suffix);
void VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F,
unsigned RetNum, unsigned ParamNum, ...);
+ void VerifyFunctionLocalMetadata(MDNode *N, Function *F,
+ SmallPtrSet<MDNode *, 32> &Visited);
void VerifyParameterAttrs(Attributes Attrs, const Type *Ty,
bool isReturnValue, const Value *V);
void VerifyFunctionAttrs(const FunctionType *FT, const AttrListPtr &Attrs,
void WriteValue(const Value *V) {
if (!V) return;
if (isa<Instruction>(V)) {
- MessagesStr << *V;
+ MessagesStr << *V << '\n';
} else {
WriteAsOperand(MessagesStr, V, true, Mod);
- MessagesStr << "\n";
+ MessagesStr << '\n';
}
}
Assert1(!GV.isConstant(), "'common' global may not be marked constant!",
&GV);
}
-
- // Verify that any metadata used in a global initializer points only to
- // other globals.
- if (MDNode *FirstNode = dyn_cast<MDNode>(GV.getInitializer())) {
- SmallVector<const MDNode *, 4> NodesToAnalyze;
- NodesToAnalyze.push_back(FirstNode);
- while (!NodesToAnalyze.empty()) {
- const MDNode *N = NodesToAnalyze.back();
- NodesToAnalyze.pop_back();
-
- for (MDNode::const_elem_iterator I = N->elem_begin(),
- E = N->elem_end(); I != E; ++I)
- if (const Value *V = *I) {
- if (const MDNode *Next = dyn_cast<MDNode>(V))
- NodesToAnalyze.push_back(Next);
- else
- Assert3(isa<Constant>(V),
- "reference to instruction from global metadata node",
- &GV, N, V);
- }
- }
- }
} else {
Assert1(GV.hasExternalLinkage() || GV.hasDLLImportLinkage() ||
GV.hasExternalWeakLinkage(),
"# formal arguments must match # of arguments for function type!",
&F, FT);
Assert1(F.getReturnType()->isFirstClassType() ||
- F.getReturnType() == Type::getVoidTy(F.getContext()) ||
+ F.getReturnType()->isVoidTy() ||
isa<StructType>(F.getReturnType()),
"Functions cannot return aggregate values!", &F);
- Assert1(!F.hasStructRetAttr() ||
- F.getReturnType() == Type::getVoidTy(F.getContext()),
+ Assert1(!F.hasStructRetAttr() || F.getReturnType()->isVoidTy(),
"Invalid struct return type!", &F);
const AttrListPtr &Attrs = F.getAttributes();
bool isLLVMdotName = F.getName().size() >= 5 &&
F.getName().substr(0, 5) == "llvm.";
- if (!isLLVMdotName)
- Assert1(F.getReturnType() != Type::getMetadataTy(F.getContext()),
- "Function may not return metadata unless it's an intrinsic", &F);
// Check that the argument values match the function type for this function...
unsigned i = 0;
Assert1(I->getType()->isFirstClassType(),
"Function arguments must have first-class types!", I);
if (!isLLVMdotName)
- Assert2(I->getType() != Type::getMetadataTy(F.getContext()),
+ Assert2(!I->getType()->isMetadataTy(),
"Function takes metadata but isn't an intrinsic", I, &F);
}
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(),
+ "blockaddress may not be used with the entry block!", Entry);
+ }
}
// If this function is actually an intrinsic, verify that it is only used in
void Verifier::visitReturnInst(ReturnInst &RI) {
Function *F = RI.getParent()->getParent();
unsigned N = RI.getNumOperands();
- if (F->getReturnType() == Type::getVoidTy(RI.getContext()))
+ if (F->getReturnType()->isVoidTy())
Assert2(N == 0,
"Found return instr that returns non-void in Function of void "
"return type!", &RI, F->getReturnType());
// Check to make sure that all of the constants in the switch instruction
// have the same type as the switched-on value.
const Type *SwitchTy = SI.getCondition()->getType();
- for (unsigned i = 1, e = SI.getNumCases(); i != e; ++i)
+ SmallPtrSet<ConstantInt*, 32> Constants;
+ for (unsigned i = 1, e = SI.getNumCases(); i != e; ++i) {
Assert1(SI.getCaseValue(i)->getType() == SwitchTy,
"Switch constants must all be same type as switch value!", &SI);
+ Assert2(Constants.insert(SI.getCaseValue(i)),
+ "Duplicate integer as switch case", &SI, SI.getCaseValue(i));
+ }
visitTerminatorInst(SI);
}
// Verify that there's no metadata unless it's a direct call to an intrinsic.
if (!CS.getCalledFunction() || CS.getCalledFunction()->getName().size() < 5 ||
CS.getCalledFunction()->getName().substr(0, 5) != "llvm.") {
- Assert1(FTy->getReturnType() != Type::getMetadataTy(I->getContext()),
- "Only intrinsics may return metadata", I);
for (FunctionType::param_iterator PI = FTy->param_begin(),
PE = FTy->param_end(); PI != PE; ++PI)
- Assert1(PI->get() != Type::getMetadataTy(I->getContext()),
+ Assert1(!PI->get()->isMetadataTy(),
"Function has metadata parameter but isn't an intrinsic", I);
}
const Type *ElTy = PTy->getElementType();
Assert2(ElTy == LI.getType(),
"Load result type does not match pointer operand type!", &LI, ElTy);
- Assert1(ElTy != Type::getMetadataTy(LI.getContext()),
- "Can't load metadata!", &LI);
visitInstruction(LI);
}
Assert2(ElTy == SI.getOperand(0)->getType(),
"Stored value type does not match pointer operand type!",
&SI, ElTy);
- Assert1(ElTy != Type::getMetadataTy(SI.getContext()),
- "Can't store metadata!", &SI);
visitInstruction(SI);
}
-void Verifier::visitAllocationInst(AllocationInst &AI) {
+void Verifier::visitAllocaInst(AllocaInst &AI) {
const PointerType *PTy = AI.getType();
Assert1(PTy->getAddressSpace() == 0,
"Allocation instruction pointer not in the generic address space!",
&AI);
Assert1(PTy->getElementType()->isSized(), "Cannot allocate unsized type",
&AI);
+ Assert1(AI.getArraySize()->getType()->isInteger(32),
+ "Alloca array size must be i32", &AI);
visitInstruction(AI);
}
Assert1(BB->getTerminator() == &I, "Terminator not at end of block!", &I);
// Check that void typed values don't have names
- Assert1(I.getType() != Type::getVoidTy(I.getContext()) || !I.hasName(),
+ Assert1(!I.getType()->isVoidTy() || !I.hasName(),
"Instruction has a name, but provides a void value!", &I);
// Check that the return value of the instruction is either void or a legal
// value type.
- Assert1(I.getType() == Type::getVoidTy(I.getContext()) ||
- I.getType()->isFirstClassType()
- || ((isa<CallInst>(I) || isa<InvokeInst>(I))
- && isa<StructType>(I.getType())),
+ Assert1(I.getType()->isVoidTy() ||
+ I.getType()->isFirstClassType(),
"Instruction returns a non-scalar type!", &I);
- // Check that the instruction doesn't produce metadata or metadata*. Calls
- // all already checked against the callee type.
- Assert1(I.getType() != Type::getMetadataTy(I.getContext()) ||
+ // Check that the instruction doesn't produce metadata. Calls are already
+ // checked against the callee type.
+ Assert1(!I.getType()->isMetadataTy() ||
isa<CallInst>(I) || isa<InvokeInst>(I),
"Invalid use of metadata!", &I);
- if (const PointerType *PTy = dyn_cast<PointerType>(I.getType()))
- Assert1(PTy->getElementType() != Type::getMetadataTy(I.getContext()),
- "Instructions may not produce pointer to metadata.", &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!
Assert1(0, "Instruction operands must be first-class values!", &I);
}
- if (const PointerType *PTy =
- dyn_cast<PointerType>(I.getOperand(i)->getType()))
- Assert1(PTy->getElementType() != Type::getMetadataTy(I.getContext()),
- "Invalid use of metadata pointer.", &I);
-
if (Function *F = dyn_cast<Function>(I.getOperand(i))) {
// Check to make sure that the "address of" an intrinsic function is never
// taken.
void Verifier::VerifyType(const Type *Ty) {
if (!Types.insert(Ty)) return;
+ Assert1(&Mod->getContext() == &Ty->getContext(),
+ "Type context does not match Module context!", Ty);
+
switch (Ty->getTypeID()) {
case Type::FunctionTyID: {
const FunctionType *FTy = cast<FunctionType>(Ty);
}
}
+/// VerifyFunctionLocalMetadata - Verify that the specified MDNode is local to
+/// specified Function.
+void Verifier::VerifyFunctionLocalMetadata(MDNode *N, Function *F,
+ SmallPtrSet<MDNode *, 32> &Visited) {
+ assert(N->isFunctionLocal() && "Should only be called on function-local MD");
+
+ // Only visit each node once.
+ if (!Visited.insert(N))
+ return;
+
+ for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
+ Value *V = N->getOperand(i);
+ if (!V) continue;
+
+ Function *ActualF = 0;
+ if (Instruction *I = dyn_cast<Instruction>(V))
+ ActualF = I->getParent()->getParent();
+ else if (BasicBlock *BB = dyn_cast<BasicBlock>(V))
+ ActualF = BB->getParent();
+ else if (Argument *A = dyn_cast<Argument>(V))
+ ActualF = A->getParent();
+ else if (MDNode *MD = dyn_cast<MDNode>(V))
+ if (MD->isFunctionLocal())
+ VerifyFunctionLocalMetadata(MD, F, Visited);
+
+ // If this was an instruction, bb, or argument, verify that it is in the
+ // function that we expect.
+ Assert1(ActualF == 0 || ActualF == F,
+ "function-local metadata used in wrong function", N);
+ }
+}
+
// Flags used by TableGen to mark intrinsic parameters with the
// LLVMExtendedElementVectorType and LLVMTruncatedElementVectorType classes.
static const unsigned ExtendedElementVectorType = 0x40000000;
#include "llvm/Intrinsics.gen"
#undef GET_INTRINSIC_VERIFIER
+ // If the intrinsic takes MDNode arguments, verify that they are either global
+ // or are local to *this* function.
+ for (unsigned i = 1, e = CI.getNumOperands(); i != e; ++i)
+ if (MDNode *MD = dyn_cast<MDNode>(CI.getOperand(i))) {
+ if (!MD->isFunctionLocal()) continue;
+ SmallPtrSet<MDNode *, 32> Visited;
+ VerifyFunctionLocalMetadata(MD, CI.getParent()->getParent(), Visited);
+ }
+
switch (ID) {
default:
break;
- case Intrinsic::dbg_declare: // llvm.dbg.declare
- if (Constant *C = dyn_cast<Constant>(CI.getOperand(1)))
- Assert1(C && !isa<ConstantPointerNull>(C),
- "invalid llvm.dbg.declare intrinsic call", &CI);
- break;
+ case Intrinsic::dbg_declare: { // llvm.dbg.declare
+ Assert1(CI.getOperand(1) && isa<MDNode>(CI.getOperand(1)),
+ "invalid llvm.dbg.declare intrinsic call 1", &CI);
+ MDNode *MD = cast<MDNode>(CI.getOperand(1));
+ Assert1(MD->getNumOperands() == 1,
+ "invalid llvm.dbg.declare intrinsic call 2", &CI);
+ if (MD->getOperand(0))
+ if (Constant *C = dyn_cast<Constant>(MD->getOperand(0)))
+ Assert1(C && !isa<ConstantPointerNull>(C),
+ "invalid llvm.dbg.declare intrinsic call 3", &CI);
+ } break;
case Intrinsic::memcpy:
case Intrinsic::memmove:
case Intrinsic::memset:
"llvm.stackprotector parameter #2 must resolve to an alloca.",
&CI);
break;
+ case Intrinsic::lifetime_start:
+ case Intrinsic::lifetime_end:
+ case Intrinsic::invariant_start:
+ Assert1(isa<ConstantInt>(CI.getOperand(1)),
+ "size argument of memory use markers must be a constant integer",
+ &CI);
+ break;
+ case Intrinsic::invariant_end:
+ Assert1(isa<ConstantInt>(CI.getOperand(2)),
+ "llvm.invariant.end parameter #2 must be a constant integer", &CI);
+ break;
}
}