X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FVerifier.cpp;h=139e035230191c3fc91da21f2d1ad8d53c774cb1;hb=9a767330f555f21d6ef311d3a348d3a44f306d35;hp=e3ecc979bf128fb837668fcc5825ffc68a23dd0a;hpb=61c70e98ac3c7504d31dd9bc81c4e9cb998e9984;p=oota-llvm.git diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index e3ecc979bf1..139e0352301 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -72,7 +72,9 @@ namespace { // Anonymous namespace for class struct PreVerifier : public FunctionPass { static char ID; // Pass ID, replacement for typeid - PreVerifier() : FunctionPass(ID) { } + PreVerifier() : FunctionPass(ID) { + initializePreVerifierPass(*PassRegistry::getPassRegistry()); + } virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); @@ -103,8 +105,8 @@ namespace { // Anonymous namespace for class char PreVerifier::ID = 0; INITIALIZE_PASS(PreVerifier, "preverify", "Preliminary module verification", - false, false); -char &PreVerifyID = PreVerifier::ID; + false, false) +static char &PreVerifyID = PreVerifier::ID; namespace { class TypeSet : public AbstractTypeUser { @@ -184,11 +186,15 @@ namespace { Verifier() : FunctionPass(ID), Broken(false), RealPass(true), action(AbortProcessAction), - Mod(0), Context(0), DT(0), MessagesStr(Messages) {} + Mod(0), Context(0), DT(0), MessagesStr(Messages) { + initializeVerifierPass(*PassRegistry::getPassRegistry()); + } explicit Verifier(VerifierFailureAction ctn) : FunctionPass(ID), Broken(false), RealPass(true), action(ctn), Mod(0), Context(0), DT(0), - MessagesStr(Messages) {} + MessagesStr(Messages) { + initializeVerifierPass(*PassRegistry::getPassRegistry()); + } bool doInitialization(Module &M) { Mod = &M; @@ -393,7 +399,10 @@ namespace { } // End anonymous namespace char Verifier::ID = 0; -INITIALIZE_PASS(Verifier, "verify", "Module Verifier", false, false); +INITIALIZE_PASS_BEGIN(Verifier, "verify", "Module Verifier", false, false) +INITIALIZE_PASS_DEPENDENCY(PreVerifier) +INITIALIZE_PASS_DEPENDENCY(DominatorTree) +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) \ @@ -462,6 +471,23 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) { "invalid linkage type for global declaration", &GV); } + if (GV.hasName() && (GV.getName() == "llvm.global_ctors" || + GV.getName() == "llvm.global_dtors")) { + Assert1(!GV.hasInitializer() || GV.hasAppendingLinkage(), + "invalid linkage for intrinsic global variable", &GV); + // Don't worry about emitting an error for it not being an array, + // visitGlobalValue will complain on appending non-array. + if (const ArrayType *ATy = dyn_cast(GV.getType())) { + const StructType *STy = dyn_cast(ATy->getElementType()); + const PointerType *FuncPtrTy = + FunctionType::get(Type::getVoidTy(*Context), false)->getPointerTo(); + Assert1(STy && STy->getNumElements() == 2 && + STy->getTypeAtIndex(0u)->isIntegerTy(32) && + STy->getTypeAtIndex(1) == FuncPtrTy, + "wrong type for intrinsic global variable", &GV); + } + } + visitGlobalValue(GV); } @@ -475,6 +501,7 @@ void Verifier::visitGlobalAlias(GlobalAlias &GA) { "Aliasee cannot be NULL!", &GA); Assert1(GA.getType() == GA.getAliasee()->getType(), "Alias and aliasee types should match!", &GA); + Assert1(!GA.hasUnnamedAddr(), "Alias cannot have unnamed_addr!", &GA); if (!isa(GA.getAliasee())) { const ConstantExpr *CE = dyn_cast(GA.getAliasee()); @@ -685,6 +712,8 @@ void Verifier::visitFunction(Function &F) { case CallingConv::Cold: case CallingConv::X86_FastCall: case CallingConv::X86_ThisCall: + case CallingConv::PTX_Kernel: + case CallingConv::PTX_Device: Assert1(!F.isVarArg(), "Varargs functions must have C calling conventions!", &F); break; @@ -814,30 +843,10 @@ void Verifier::visitReturnInst(ReturnInst &RI) { Assert2(N == 0, "Found return instr that returns non-void in Function of void " "return type!", &RI, F->getReturnType()); - else if (N == 1 && F->getReturnType() == RI.getOperand(0)->getType()) { - // Exactly one return value and it matches the return type. Good. - } else if (const StructType *STy = dyn_cast(F->getReturnType())) { - // The return type is a struct; check for multiple return values. - Assert2(STy->getNumElements() == N, - "Incorrect number of return values in ret instruction!", - &RI, F->getReturnType()); - for (unsigned i = 0; i != N; ++i) - Assert2(STy->getElementType(i) == RI.getOperand(i)->getType(), - "Function return type does not match operand " - "type of return inst!", &RI, F->getReturnType()); - } else if (const ArrayType *ATy = dyn_cast(F->getReturnType())) { - // The return type is an array; check for multiple return values. - Assert2(ATy->getNumElements() == N, - "Incorrect number of return values in ret instruction!", - &RI, F->getReturnType()); - for (unsigned i = 0; i != N; ++i) - Assert2(ATy->getElementType() == RI.getOperand(i)->getType(), - "Function return type does not match operand " - "type of return inst!", &RI, F->getReturnType()); - } else { - CheckFailed("Function return type does not match operand " - "type of return inst!", &RI, F->getReturnType()); - } + else + Assert2(N == 1 && F->getReturnType() == RI.getOperand(0)->getType(), + "Function return type does not match operand " + "type of return inst!", &RI, F->getReturnType()); // Check to make sure that the return value has necessary properties for // terminators... @@ -1636,6 +1645,9 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { Assert1(isa(CI.getArgOperand(3)), "alignment argument of memory intrinsics must be a constant int", &CI); + Assert1(isa(CI.getArgOperand(4)), + "isvolatile argument of memory intrinsics must be a constant int", + &CI); break; case Intrinsic::gcroot: case Intrinsic::gcwrite: @@ -1643,10 +1655,14 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { if (ID == Intrinsic::gcroot) { AllocaInst *AI = dyn_cast(CI.getArgOperand(0)->stripPointerCasts()); - Assert1(AI && AI->getType()->getElementType()->isPointerTy(), - "llvm.gcroot parameter #1 must be a pointer alloca.", &CI); + Assert1(AI, "llvm.gcroot parameter #1 must be an alloca.", &CI); Assert1(isa(CI.getArgOperand(1)), "llvm.gcroot parameter #2 must be a constant.", &CI); + if (!AI->getType()->getElementType()->isPointerTy()) { + Assert1(!isa(CI.getArgOperand(1)), + "llvm.gcroot parameter #1 must either be a pointer alloca, " + "or argument #2 must be a non-null constant.", &CI); + } } Assert1(CI.getParent()->getParent()->hasGC(),