X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FIR%2FVerifier.cpp;h=f64d4e2fddc963039137e206037d99e9542a872b;hp=b6df70869b54bf1d84019e42dc0e9352ef8a25aa;hb=32310b78d7799109e0e6d99a317b15aa8e8b6216;hpb=751c4be70521ab89c9dc4f2f2fa28e54659b4865;ds=sidebyside diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index b6df70869b5..f64d4e2fddc 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -39,8 +39,7 @@ // only by the unwind edge of an invoke instruction. // * A landingpad instruction must be the first non-PHI instruction in the // block. -// * All landingpad instructions must use the same personality function with -// the same function. +// * Landingpad instructions must be in a function with a personality function. // * All other things that are tested by asserts spread about the code... // //===----------------------------------------------------------------------===// @@ -92,6 +91,10 @@ struct VerifierSupport { : OS(OS), M(nullptr), Broken(false) {} private: + template void Write(const ilist_iterator &I) { + Write(&*I); + } + void Write(const Value *V) { if (!V) return; @@ -184,6 +187,9 @@ class Verifier : public InstVisitor, VerifierSupport { /// \brief Track unresolved string-based type references. SmallDenseMap UnresolvedTypeRefs; + /// \brief The result type for a landingpad. + Type *LandingPadResultTy; + /// \brief Whether we've seen a call to @llvm.localescape in this function /// already. bool SawFrameEscape; @@ -194,7 +200,8 @@ class Verifier : public InstVisitor, VerifierSupport { public: explicit Verifier(raw_ostream &OS) - : VerifierSupport(OS), Context(nullptr), SawFrameEscape(false) {} + : VerifierSupport(OS), Context(nullptr), LandingPadResultTy(nullptr), + SawFrameEscape(false) {} bool verify(const Function &F) { M = F.getParent(); @@ -228,6 +235,7 @@ public: // FIXME: We strip const here because the inst visitor strips const. visit(const_cast(F)); InstsInThisBlock.clear(); + LandingPadResultTy = nullptr; SawFrameEscape = false; return !Broken; @@ -297,12 +305,12 @@ private: void visitFunction(const Function &F); void visitBasicBlock(BasicBlock &BB); void visitRangeMetadata(Instruction& I, MDNode* Range, Type* Ty); + void visitDereferenceableMetadata(Instruction& I, MDNode* MD); template bool isValidMetadataArray(const MDTuple &N); #define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) void visit##CLASS(const CLASS &N); #include "llvm/IR/Metadata.def" void visitDIScope(const DIScope &N); - void visitDIDerivedTypeBase(const DIDerivedTypeBase &N); void visitDIVariable(const DIVariable &N); void visitDILexicalBlockBase(const DILexicalBlockBase &N); void visitDITemplateParameter(const DITemplateParameter &N); @@ -379,11 +387,14 @@ private: void visitAllocaInst(AllocaInst &AI); void visitExtractValueInst(ExtractValueInst &EVI); void visitInsertValueInst(InsertValueInst &IVI); + void visitEHPadPredecessors(Instruction &I); void visitLandingPadInst(LandingPadInst &LPI); - void visitCatchBlockInst(CatchBlockInst &CBI); - void visitCatchEndBlockInst(CatchEndBlockInst &CEBI); - void visitCleanupBlockInst(CleanupBlockInst &CBI); - void visitTerminateBlockInst(TerminateBlockInst &TBI); + void visitCatchPadInst(CatchPadInst &CPI); + void visitCatchEndPadInst(CatchEndPadInst &CEPI); + void visitCleanupPadInst(CleanupPadInst &CPI); + void visitCleanupEndPadInst(CleanupEndPadInst &CEPI); + void visitCleanupReturnInst(CleanupReturnInst &CRI); + void visitTerminatePadInst(TerminatePadInst &TPI); void VerifyCallSite(CallSite CS); void verifyMustTailCall(CallInst &CI); @@ -783,39 +794,10 @@ void Verifier::visitDIBasicType(const DIBasicType &N) { "invalid tag", &N); } -void Verifier::visitDIDerivedTypeBase(const DIDerivedTypeBase &N) { +void Verifier::visitDIDerivedType(const DIDerivedType &N) { // Common scope checks. visitDIScope(N); - Assert(isScopeRef(N, N.getScope()), "invalid scope", &N, N.getScope()); - Assert(isTypeRef(N, N.getBaseType()), "invalid base type", &N, - N.getBaseType()); - - // FIXME: Sink this into the subclass verifies. - if (!N.getFile() || N.getFile()->getFilename().empty()) { - // Check whether the filename is allowed to be empty. - uint16_t Tag = N.getTag(); - Assert( - Tag == dwarf::DW_TAG_const_type || Tag == dwarf::DW_TAG_volatile_type || - Tag == dwarf::DW_TAG_pointer_type || - Tag == dwarf::DW_TAG_ptr_to_member_type || - Tag == dwarf::DW_TAG_reference_type || - Tag == dwarf::DW_TAG_rvalue_reference_type || - Tag == dwarf::DW_TAG_restrict_type || - Tag == dwarf::DW_TAG_array_type || - Tag == dwarf::DW_TAG_enumeration_type || - Tag == dwarf::DW_TAG_subroutine_type || - Tag == dwarf::DW_TAG_inheritance || Tag == dwarf::DW_TAG_friend || - Tag == dwarf::DW_TAG_structure_type || - Tag == dwarf::DW_TAG_member || Tag == dwarf::DW_TAG_typedef, - "derived/composite type requires a filename", &N, N.getFile()); - } -} - -void Verifier::visitDIDerivedType(const DIDerivedType &N) { - // Common derived type checks. - visitDIDerivedTypeBase(N); - Assert(N.getTag() == dwarf::DW_TAG_typedef || N.getTag() == dwarf::DW_TAG_pointer_type || N.getTag() == dwarf::DW_TAG_ptr_to_member_type || @@ -832,6 +814,10 @@ void Verifier::visitDIDerivedType(const DIDerivedType &N) { Assert(isTypeRef(N, N.getExtraData()), "invalid pointer to member type", &N, N.getExtraData()); } + + Assert(isScopeRef(N, N.getScope()), "invalid scope", &N, N.getScope()); + Assert(isTypeRef(N, N.getBaseType()), "invalid base type", &N, + N.getBaseType()); } static bool hasConflictingReferenceFlags(unsigned Flags) { @@ -849,17 +835,20 @@ void Verifier::visitTemplateParams(const MDNode &N, const Metadata &RawParams) { } void Verifier::visitDICompositeType(const DICompositeType &N) { - // Common derived type checks. - visitDIDerivedTypeBase(N); + // Common scope checks. + visitDIScope(N); Assert(N.getTag() == dwarf::DW_TAG_array_type || N.getTag() == dwarf::DW_TAG_structure_type || N.getTag() == dwarf::DW_TAG_union_type || N.getTag() == dwarf::DW_TAG_enumeration_type || - N.getTag() == dwarf::DW_TAG_subroutine_type || N.getTag() == dwarf::DW_TAG_class_type, "invalid tag", &N); + Assert(isScopeRef(N, N.getScope()), "invalid scope", &N, N.getScope()); + Assert(isTypeRef(N, N.getBaseType()), "invalid base type", &N, + N.getBaseType()); + Assert(!N.getRawElements() || isa(N.getRawElements()), "invalid composite elements", &N, N.getRawElements()); Assert(isTypeRef(N, N.getRawVTableHolder()), "invalid vtable holder", &N, @@ -870,6 +859,12 @@ void Verifier::visitDICompositeType(const DICompositeType &N) { &N); if (auto *Params = N.getRawTemplateParams()) visitTemplateParams(N, *Params); + + if (N.getTag() == dwarf::DW_TAG_class_type || + N.getTag() == dwarf::DW_TAG_union_type) { + Assert(N.getFile() && !N.getFile()->getFilename().empty(), + "class/union requires a filename", &N, N.getFile()); + } } void Verifier::visitDISubroutineType(const DISubroutineType &N) { @@ -889,6 +884,7 @@ void Verifier::visitDIFile(const DIFile &N) { } void Verifier::visitDICompileUnit(const DICompileUnit &N) { + Assert(N.isDistinct(), "compile units must be distinct", &N); Assert(N.getTag() == dwarf::DW_TAG_compile_unit, "invalid tag", &N); // Don't bother verifying the compilation directory or producer string @@ -965,6 +961,9 @@ void Verifier::visitDISubprogram(const DISubprogram &N) { Assert(!hasConflictingReferenceFlags(N.getFlags()), "invalid reference flags", &N); + if (N.isDefinition()) + Assert(N.isDistinct(), "subprogram definitions must be distinct", &N); + auto *F = N.getFunction(); if (!F) return; @@ -1079,9 +1078,7 @@ void Verifier::visitDILocalVariable(const DILocalVariable &N) { // Checks common to all variables. visitDIVariable(N); - Assert(N.getTag() == dwarf::DW_TAG_auto_variable || - N.getTag() == dwarf::DW_TAG_arg_variable, - "invalid tag", &N); + Assert(N.getTag() == dwarf::DW_TAG_variable, "invalid tag", &N); Assert(N.getRawScope() && isa(N.getRawScope()), "local variable requires a valid scope", &N, N.getRawScope()); } @@ -1277,7 +1274,8 @@ void Verifier::VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx, I->getKindAsEnum() == Attribute::Cold || I->getKindAsEnum() == Attribute::OptimizeNone || I->getKindAsEnum() == Attribute::JumpTable || - I->getKindAsEnum() == Attribute::Convergent) { + I->getKindAsEnum() == Attribute::Convergent || + I->getKindAsEnum() == Attribute::ArgMemOnly) { if (!isFunction) { CheckFailed("Attribute '" + I->getAsString() + "' only applies to functions!", V); @@ -1368,7 +1366,7 @@ void Verifier::VerifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty, V); if (PointerType *PTy = dyn_cast(Ty)) { - SmallPtrSet Visited; + SmallPtrSet Visited; if (!PTy->getElementType()->isSized(&Visited)) { Assert(!Attrs.hasAttribute(Idx, Attribute::ByVal) && !Attrs.hasAttribute(Idx, Attribute::InAlloca), @@ -1535,8 +1533,9 @@ void Verifier::VerifyStatepoint(ImmutableCallSite CS) { const Instruction &CI = *CS.getInstruction(); - Assert(!CS.doesNotAccessMemory() && !CS.onlyReadsMemory(), - "gc.statepoint must read and write memory to preserve " + Assert(!CS.doesNotAccessMemory() && !CS.onlyReadsMemory() && + !CS.onlyAccessesArgMemory(), + "gc.statepoint must read and write all memory to preserve " "reordering restrictions required by safepoint semantics", &CI); @@ -1556,17 +1555,11 @@ void Verifier::VerifyStatepoint(ImmutableCallSite CS) { &CI); const Value *Target = CS.getArgument(2); - const PointerType *PT = dyn_cast(Target->getType()); + auto *PT = dyn_cast(Target->getType()); Assert(PT && PT->getElementType()->isFunctionTy(), "gc.statepoint callee must be of function pointer type", &CI, Target); FunctionType *TargetFuncType = cast(PT->getElementType()); - if (NumPatchBytes) - Assert(isa(Target->stripPointerCasts()), - "gc.statepoint must have null as call target if number of patchable " - "bytes is non zero", - &CI); - const Value *NumCallArgsV = CS.getArgument(3); Assert(isa(NumCallArgsV), "gc.statepoint number of arguments to underlying call " @@ -1745,11 +1738,18 @@ void Verifier::visitFunction(const Function &F) { FT->getParamType(i)); Assert(I->getType()->isFirstClassType(), "Function arguments must have first-class types!", I); - if (!isLLVMdotName) + if (!isLLVMdotName) { Assert(!I->getType()->isMetadataTy(), "Function takes metadata but isn't an intrinsic", I, &F); + Assert(!I->getType()->isTokenTy(), + "Function takes token but isn't an intrinsic", I, &F); + } } + if (!isLLVMdotName) + Assert(!F.getReturnType()->isTokenTy(), + "Functions returns a token but isn't an intrinsic", &F); + // Get the function metadata attachments. SmallVector, 4> MDs; F.getAllMetadata(MDs); @@ -1784,8 +1784,20 @@ void Verifier::visitFunction(const Function &F) { } // Visit metadata attachments. - for (const auto &I : MDs) + for (const auto &I : MDs) { + // Verify that the attachment is legal. + switch (I.first) { + default: + break; + case LLVMContext::MD_dbg: + Assert(isa(I.second), + "function !dbg attachment must be a subprogram", &F, I.second); + break; + } + + // Verify the metadata itself. visitMDNode(*I.second); + } } // If this function is actually an intrinsic, verify that it is only used in @@ -2196,6 +2208,9 @@ void Verifier::visitPHINode(PHINode &PN) { isa(--BasicBlock::iterator(&PN)), "PHI nodes not grouped at top of basic block!", &PN, PN.getParent()); + // Check that a PHI doesn't yield a Token. + Assert(!PN.getType()->isTokenTy(), "PHI nodes cannot have token type!"); + // Check that all of the values of the PHI node have the same type as the // result, and that the incoming blocks are really basic blocks. for (Value *IncValue : PN.incoming_values()) { @@ -2298,12 +2313,19 @@ void Verifier::VerifyCallSite(CallSite CS) { // Verify that there's no metadata unless it's a direct call to an intrinsic. if (CS.getCalledFunction() == nullptr || !CS.getCalledFunction()->getName().startswith("llvm.")) { - for (FunctionType::param_iterator PI = FTy->param_begin(), - PE = FTy->param_end(); PI != PE; ++PI) - Assert(!(*PI)->isMetadataTy(), + for (Type *ParamTy : FTy->params()) { + Assert(!ParamTy->isMetadataTy(), "Function has metadata parameter but isn't an intrinsic", I); + Assert(!ParamTy->isTokenTy(), + "Function has token parameter but isn't an intrinsic", I); + } } + // Verify that indirect calls don't return tokens. + if (CS.getCalledFunction() == nullptr) + Assert(!FTy->getReturnType()->isTokenTy(), + "Return type cannot be token for indirect call!"); + if (Function *F = CS.getCalledFunction()) if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID()) visitIntrinsicCallSite(ID, CS); @@ -2408,10 +2430,10 @@ void Verifier::visitCallInst(CallInst &CI) { void Verifier::visitInvokeInst(InvokeInst &II) { VerifyCallSite(&II); - // Verify that there is an exception block instruction is the first non-PHI - // instruction of the 'unwind' destination. + // Verify that the first non-PHI instruction of the unwind destination is an + // exception handling instruction. Assert( - II.getUnwindDest()->isEHBlock(), + II.getUnwindDest()->isEHPad(), "The unwind destination does not have an exception handling instruction!", &II); @@ -2682,7 +2704,7 @@ void Verifier::visitStoreInst(StoreInst &SI) { } void Verifier::visitAllocaInst(AllocaInst &AI) { - SmallPtrSet Visited; + SmallPtrSet Visited; PointerType *PTy = AI.getType(); Assert(PTy->getAddressSpace() == 0, "Allocation instruction pointer not in the generic address space!", @@ -2781,23 +2803,64 @@ void Verifier::visitInsertValueInst(InsertValueInst &IVI) { visitInstruction(IVI); } -void Verifier::visitLandingPadInst(LandingPadInst &LPI) { - BasicBlock *BB = LPI.getParent(); +void Verifier::visitEHPadPredecessors(Instruction &I) { + assert(I.isEHPad()); + + BasicBlock *BB = I.getParent(); + Function *F = BB->getParent(); + + Assert(BB != &F->getEntryBlock(), "EH pad cannot be in entry block.", &I); + + if (auto *LPI = dyn_cast(&I)) { + // The landingpad instruction defines its parent as a landing pad block. The + // landing pad block may be branched to only by the unwind edge of an + // invoke. + for (BasicBlock *PredBB : predecessors(BB)) { + const auto *II = dyn_cast(PredBB->getTerminator()); + Assert(II && II->getUnwindDest() == BB && II->getNormalDest() != BB, + "Block containing LandingPadInst must be jumped to " + "only by the unwind edge of an invoke.", + LPI); + } + return; + } + + for (BasicBlock *PredBB : predecessors(BB)) { + TerminatorInst *TI = PredBB->getTerminator(); + if (auto *II = dyn_cast(TI)) + Assert(II->getUnwindDest() == BB && II->getNormalDest() != BB, + "EH pad must be jumped to via an unwind edge", &I, II); + else if (auto *CPI = dyn_cast(TI)) + Assert(CPI->getUnwindDest() == BB && CPI->getNormalDest() != BB, + "EH pad must be jumped to via an unwind edge", &I, CPI); + else if (isa(TI)) + ; + else if (isa(TI)) + ; + else if (isa(TI)) + ; + else if (isa(TI)) + ; + else + Assert(false, "EH pad must be jumped to via an unwind edge", &I, TI); + } +} +void Verifier::visitLandingPadInst(LandingPadInst &LPI) { // The landingpad instruction is ill-formed if it doesn't have any clauses and // isn't a cleanup. Assert(LPI.getNumClauses() > 0 || LPI.isCleanup(), "LandingPadInst needs at least one clause or to be a cleanup.", &LPI); - // The landingpad instruction defines its parent as a landing pad block. The - // landing pad block may be branched to only by the unwind edge of an invoke. - for (pred_iterator I = pred_begin(BB), E = pred_end(BB); I != E; ++I) { - const InvokeInst *II = dyn_cast((*I)->getTerminator()); - Assert(II && II->getUnwindDest() == BB && II->getNormalDest() != BB, - "Block containing LandingPadInst must be jumped to " - "only by the unwind edge of an invoke.", + visitEHPadPredecessors(LPI); + + if (!LandingPadResultTy) + LandingPadResultTy = LPI.getType(); + else + Assert(LandingPadResultTy == LPI.getType(), + "The landingpad instruction should have a consistent result type " + "inside a function.", &LPI); - } Function *F = LPI.getParent()->getParent(); Assert(F->hasPersonalityFn(), @@ -2824,70 +2887,174 @@ void Verifier::visitLandingPadInst(LandingPadInst &LPI) { visitInstruction(LPI); } -void Verifier::visitCatchBlockInst(CatchBlockInst &CBI) { - BasicBlock *BB = CBI.getParent(); +void Verifier::visitCatchPadInst(CatchPadInst &CPI) { + visitEHPadPredecessors(CPI); + + BasicBlock *BB = CPI.getParent(); + Function *F = BB->getParent(); + Assert(F->hasPersonalityFn(), + "CatchPadInst needs to be in a function with a personality.", &CPI); + + // The catchpad instruction must be the first non-PHI instruction in the + // block. + Assert(BB->getFirstNonPHI() == &CPI, + "CatchPadInst not the first non-PHI instruction in the block.", + &CPI); + + if (!BB->getSinglePredecessor()) + for (BasicBlock *PredBB : predecessors(BB)) { + Assert(!isa(PredBB->getTerminator()), + "CatchPadInst with CatchPadInst predecessor cannot have any other " + "predecessors.", + &CPI); + } + + BasicBlock *UnwindDest = CPI.getUnwindDest(); + Instruction *I = UnwindDest->getFirstNonPHI(); + Assert( + isa(I) || isa(I), + "CatchPadInst must unwind to a CatchPadInst or a CatchEndPadInst.", + &CPI); + + visitTerminatorInst(CPI); +} + +void Verifier::visitCatchEndPadInst(CatchEndPadInst &CEPI) { + visitEHPadPredecessors(CEPI); + BasicBlock *BB = CEPI.getParent(); Function *F = BB->getParent(); Assert(F->hasPersonalityFn(), - "CatchBlockInst needs to be in a function with a personality.", &CBI); + "CatchEndPadInst needs to be in a function with a personality.", + &CEPI); - // The catchblock instruction must be the first non-PHI instruction in the + // The catchendpad instruction must be the first non-PHI instruction in the // block. - Assert(BB->getFirstNonPHI() == &CBI, - "CatchBlockInst not the first non-PHI instruction in the block.", - &CBI); + Assert(BB->getFirstNonPHI() == &CEPI, + "CatchEndPadInst not the first non-PHI instruction in the block.", + &CEPI); - visitTerminatorInst(CBI); + unsigned CatchPadsSeen = 0; + for (BasicBlock *PredBB : predecessors(BB)) + if (isa(PredBB->getTerminator())) + ++CatchPadsSeen; + + Assert(CatchPadsSeen <= 1, "CatchEndPadInst must have no more than one " + "CatchPadInst predecessor.", + &CEPI); + + if (BasicBlock *UnwindDest = CEPI.getUnwindDest()) { + Instruction *I = UnwindDest->getFirstNonPHI(); + Assert( + I->isEHPad() && !isa(I), + "CatchEndPad must unwind to an EH block which is not a landingpad.", + &CEPI); + } + + visitTerminatorInst(CEPI); } -void Verifier::visitCatchEndBlockInst(CatchEndBlockInst &CEBI) { - BasicBlock *BB = CEBI.getParent(); +void Verifier::visitCleanupPadInst(CleanupPadInst &CPI) { + visitEHPadPredecessors(CPI); + + BasicBlock *BB = CPI.getParent(); Function *F = BB->getParent(); Assert(F->hasPersonalityFn(), - "CatchEndBlockInst needs to be in a function with a personality.", - &CEBI); + "CleanupPadInst needs to be in a function with a personality.", &CPI); - // The catchendblock instruction must be the first non-PHI instruction in the + // The cleanuppad instruction must be the first non-PHI instruction in the // block. - Assert(BB->getFirstNonPHI() == &CEBI, - "CatchEndBlockInst not the first non-PHI instruction in the block.", - &CEBI); + Assert(BB->getFirstNonPHI() == &CPI, + "CleanupPadInst not the first non-PHI instruction in the block.", + &CPI); + + User *FirstUser = nullptr; + BasicBlock *FirstUnwindDest = nullptr; + for (User *U : CPI.users()) { + BasicBlock *UnwindDest; + if (CleanupReturnInst *CRI = dyn_cast(U)) { + UnwindDest = CRI->getUnwindDest(); + } else { + UnwindDest = cast(U)->getUnwindDest(); + } + + if (!FirstUser) { + FirstUser = U; + FirstUnwindDest = UnwindDest; + } else { + Assert(UnwindDest == FirstUnwindDest, + "Cleanuprets/cleanupendpads from the same cleanuppad must " + "have the same unwind destination", + FirstUser, U); + } + } - visitTerminatorInst(CEBI); + visitInstruction(CPI); } -void Verifier::visitCleanupBlockInst(CleanupBlockInst &CBI) { - BasicBlock *BB = CBI.getParent(); +void Verifier::visitCleanupEndPadInst(CleanupEndPadInst &CEPI) { + visitEHPadPredecessors(CEPI); + BasicBlock *BB = CEPI.getParent(); Function *F = BB->getParent(); Assert(F->hasPersonalityFn(), - "CleanupBlockInst needs to be in a function with a personality.", &CBI); + "CleanupEndPadInst needs to be in a function with a personality.", + &CEPI); - // The cleanupblock instruction must be the first non-PHI instruction in the + // The cleanupendpad instruction must be the first non-PHI instruction in the // block. - Assert(BB->getFirstNonPHI() == &CBI, - "CleanupBlockInst not the first non-PHI instruction in the block.", - &CBI); + Assert(BB->getFirstNonPHI() == &CEPI, + "CleanupEndPadInst not the first non-PHI instruction in the block.", + &CEPI); + + if (BasicBlock *UnwindDest = CEPI.getUnwindDest()) { + Instruction *I = UnwindDest->getFirstNonPHI(); + Assert( + I->isEHPad() && !isa(I), + "CleanupEndPad must unwind to an EH block which is not a landingpad.", + &CEPI); + } + + visitTerminatorInst(CEPI); +} + +void Verifier::visitCleanupReturnInst(CleanupReturnInst &CRI) { + if (BasicBlock *UnwindDest = CRI.getUnwindDest()) { + Instruction *I = UnwindDest->getFirstNonPHI(); + Assert(I->isEHPad() && !isa(I), + "CleanupReturnInst must unwind to an EH block which is not a " + "landingpad.", + &CRI); + } - visitInstruction(CBI); + visitTerminatorInst(CRI); } -void Verifier::visitTerminateBlockInst(TerminateBlockInst &TBI) { - BasicBlock *BB = TBI.getParent(); +void Verifier::visitTerminatePadInst(TerminatePadInst &TPI) { + visitEHPadPredecessors(TPI); + BasicBlock *BB = TPI.getParent(); Function *F = BB->getParent(); Assert(F->hasPersonalityFn(), - "TerminateBlockInst needs to be in a function with a personality.", - &TBI); + "TerminatePadInst needs to be in a function with a personality.", + &TPI); - // The terminateblock instruction must be the first non-PHI instruction in the + // The terminatepad instruction must be the first non-PHI instruction in the // block. - Assert(BB->getFirstNonPHI() == &TBI, - "TerminateBlockInst not the first non-PHI instruction in the block.", - &TBI); + Assert(BB->getFirstNonPHI() == &TPI, + "TerminatePadInst not the first non-PHI instruction in the block.", + &TPI); + + if (BasicBlock *UnwindDest = TPI.getUnwindDest()) { + Instruction *I = UnwindDest->getFirstNonPHI(); + Assert(I->isEHPad() && !isa(I), + "TerminatePadInst must unwind to an EH block which is not a " + "landingpad.", + &TPI); + } - visitTerminatorInst(TBI); + visitTerminatorInst(TPI); } void Verifier::verifyDominatesUse(Instruction &I, unsigned i) { @@ -2905,6 +3072,19 @@ void Verifier::verifyDominatesUse(Instruction &I, unsigned i) { "Instruction does not dominate all uses!", Op, &I); } +void Verifier::visitDereferenceableMetadata(Instruction& I, MDNode* MD) { + Assert(I.getType()->isPointerTy(), "dereferenceable, dereferenceable_or_null " + "apply only to pointer types", &I); + Assert(isa(I), + "dereferenceable, dereferenceable_or_null apply only to load" + " instructions, use attributes for calls or invokes", &I); + Assert(MD->getNumOperands() == 1, "dereferenceable, dereferenceable_or_null " + "take one operand!", &I); + ConstantInt *CI = mdconst::dyn_extract(MD->getOperand(0)); + Assert(CI && CI->getType()->isIntegerTy(64), "dereferenceable, " + "dereferenceable_or_null metadata value must be an i64!", &I); +} + /// verifyInstruction - Verify that an instruction is well formed. /// void Verifier::visitInstruction(Instruction &I) { @@ -3041,6 +3221,28 @@ void Verifier::visitInstruction(Instruction &I) { &I); } + if (MDNode *MD = I.getMetadata(LLVMContext::MD_dereferenceable)) + visitDereferenceableMetadata(I, MD); + + if (MDNode *MD = I.getMetadata(LLVMContext::MD_dereferenceable_or_null)) + visitDereferenceableMetadata(I, MD); + + if (MDNode *AlignMD = I.getMetadata(LLVMContext::MD_align)) { + Assert(I.getType()->isPointerTy(), "align applies only to pointer types", + &I); + Assert(isa(I), "align applies only to load instructions, " + "use attributes for calls or invokes", &I); + Assert(AlignMD->getNumOperands() == 1, "align takes one operand!", &I); + ConstantInt *CI = mdconst::dyn_extract(AlignMD->getOperand(0)); + Assert(CI && CI->getType()->isIntegerTy(64), + "align metadata value must be an i64!", &I); + uint64_t Align = CI->getZExtValue(); + Assert(isPowerOf2_64(Align), + "align metadata value must be a power of 2!", &I); + Assert(Align <= Value::MaximumAlignment, + "alignment is larger that implementation defined limit", &I); + } + if (MDNode *N = I.getDebugLoc().getAsMDNode()) { Assert(isa(N), "invalid !dbg metadata attachment", &I, N); visitMDNode(*N); @@ -3068,6 +3270,7 @@ bool Verifier::VerifyIntrinsicType(Type *Ty, case IITDescriptor::Void: return !Ty->isVoidTy(); case IITDescriptor::VarArg: return true; case IITDescriptor::MMX: return !Ty->isX86_MMXTy(); + case IITDescriptor::Token: return !Ty->isTokenTy(); case IITDescriptor::Metadata: return !Ty->isMetadataTy(); case IITDescriptor::Half: return !Ty->isHalfTy(); case IITDescriptor::Float: return !Ty->isFloatTy(); @@ -3409,9 +3612,8 @@ void Verifier::visitIntrinsicCallSite(Intrinsic::ID ID, CallSite CS) { // Assert that result type matches wrapped callee. const Value *Target = StatepointCS.getArgument(2); - const PointerType *PT = cast(Target->getType()); - const FunctionType *TargetFuncType = - cast(PT->getElementType()); + auto *PT = cast(Target->getType()); + auto *TargetFuncType = cast(PT->getElementType()); Assert(CS.getType() == TargetFuncType->getReturnType(), "gc.result result type does not match wrapped callee", CS); break; @@ -3518,6 +3720,12 @@ void Verifier::visitIntrinsicCallSite(Intrinsic::ID ID, CallSite CS) { "gc.relocate: relocating a pointer shouldn't change its address space", CS); break; } + case Intrinsic::eh_exceptioncode: + case Intrinsic::eh_exceptionpointer: { + Assert(isa(CS.getArgOperand(0)), + "eh.exceptionpointer argument must be a catchpad", CS); + break; + } }; } @@ -3668,7 +3876,7 @@ void Verifier::verifyTypeRefs() { for (auto *CU : CUs->operands()) if (auto Ts = cast(CU)->getRetainedTypes()) for (DIType *Op : Ts) - if (auto *T = dyn_cast(Op)) + if (auto *T = dyn_cast_or_null(Op)) if (auto *S = T->getRawIdentifier()) { UnresolvedTypeRefs.erase(S); TypeRefs.insert(std::make_pair(S, T));