X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FIR%2FVerifier.cpp;h=1a22d37ba8af94320761acffe28d53d520824649;hp=e14f1036912eec6717cfcff6ff67f502c47d20dd;hb=7e54c38de03268a98f329069556b7bcf166c8f05;hpb=4ba5d91a08249edc55c521f1c94ced9062e6cb58 diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index e14f1036912..1a22d37ba8a 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,16 @@ struct VerifierSupport { : OS(OS), M(nullptr), Broken(false) {} private: + template void Write(const ilist_iterator &I) { + Write(&*I); + } + + void Write(const Module *M) { + if (!M) + return; + OS << "; ModuleID = '" << M->getModuleIdentifier() << "'\n"; + } + void Write(const Value *V) { if (!V) return; @@ -102,6 +111,9 @@ private: OS << '\n'; } } + void Write(ImmutableCallSite CS) { + Write(CS.getInstruction()); + } void Write(const Metadata *MD) { if (!MD) @@ -181,22 +193,25 @@ class Verifier : public InstVisitor, VerifierSupport { /// \brief Track unresolved string-based type references. SmallDenseMap UnresolvedTypeRefs; - /// \brief The personality function referenced by the LandingPadInsts. - /// All LandingPadInsts within the same function must use the same - /// personality function. - const Value *PersonalityFn; + /// \brief The result type for a landingpad. + Type *LandingPadResultTy; - /// \brief Whether we've seen a call to @llvm.frameescape in this function + /// \brief Whether we've seen a call to @llvm.localescape in this function /// already. bool SawFrameEscape; - /// Stores the count of how many objects were passed to llvm.frameescape for a - /// given function and the largest index passed to llvm.framerecover. + /// Stores the count of how many objects were passed to llvm.localescape for a + /// given function and the largest index passed to llvm.localrecover. DenseMap> FrameEscapeInfo; + /// Cache of constants visited in search of ConstantExprs. + SmallPtrSet ConstantExprVisited; + + void checkAtomicMemAccessSize(const Module *M, Type *Ty, + const Instruction *I); public: explicit Verifier(raw_ostream &OS) - : VerifierSupport(OS), Context(nullptr), PersonalityFn(nullptr), + : VerifierSupport(OS), Context(nullptr), LandingPadResultTy(nullptr), SawFrameEscape(false) {} bool verify(const Function &F) { @@ -231,7 +246,7 @@ public: // FIXME: We strip const here because the inst visitor strips const. visit(const_cast(F)); InstsInThisBlock.clear(); - PersonalityFn = nullptr; + LandingPadResultTy = nullptr; SawFrameEscape = false; return !Broken; @@ -301,15 +316,15 @@ 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 visitMDScope(const MDScope &N); - void visitMDDerivedTypeBase(const MDDerivedTypeBase &N); - void visitMDVariable(const MDVariable &N); - void visitMDLexicalBlockBase(const MDLexicalBlockBase &N); - void visitMDTemplateParameter(const MDTemplateParameter &N); + void visitDIScope(const DIScope &N); + void visitDIVariable(const DIVariable &N); + void visitDILexicalBlockBase(const DILexicalBlockBase &N); + void visitDITemplateParameter(const DITemplateParameter &N); void visitTemplateParams(const MDNode &N, const Metadata &RawParams); @@ -321,17 +336,17 @@ private: /// \brief Check for a valid type reference. /// - /// Checks for subclasses of \a MDType, or \a isValidUUID(). + /// Checks for subclasses of \a DIType, or \a isValidUUID(). bool isTypeRef(const MDNode &N, const Metadata *MD); /// \brief Check for a valid scope reference. /// - /// Checks for subclasses of \a MDScope, or \a isValidUUID(). + /// Checks for subclasses of \a DIScope, or \a isValidUUID(). bool isScopeRef(const MDNode &N, const Metadata *MD); /// \brief Check for a valid debug info reference. /// - /// Checks for subclasses of \a DebugNode, or \a isValidUUID(). + /// Checks for subclasses of \a DINode, or \a isValidUUID(). bool isDIRef(const MDNode &N, const Metadata *MD); // InstVisitor overrides... @@ -374,7 +389,7 @@ private: void visitSelectInst(SelectInst &SI); void visitUserOp1(Instruction &I); void visitUserOp2(Instruction &I) { visitUserOp1(I); } - void visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI); + void visitIntrinsicCallSite(Intrinsic::ID ID, CallSite CS); template void visitDbgIntrinsic(StringRef Kind, DbgIntrinsicTy &DII); void visitAtomicCmpXchgInst(AtomicCmpXchgInst &CXI); @@ -383,7 +398,13 @@ private: void visitAllocaInst(AllocaInst &AI); void visitExtractValueInst(ExtractValueInst &EVI); void visitInsertValueInst(InsertValueInst &IVI); + void visitEHPadPredecessors(Instruction &I); void visitLandingPadInst(LandingPadInst &LPI); + void visitCatchPadInst(CatchPadInst &CPI); + void visitCatchReturnInst(CatchReturnInst &CatchReturn); + void visitCleanupPadInst(CleanupPadInst &CPI); + void visitCatchSwitchInst(CatchSwitchInst &CatchSwitch); + void visitCleanupReturnInst(CleanupReturnInst &CRI); void VerifyCallSite(CallSite CS); void verifyMustTailCall(CallInst &CI); @@ -400,8 +421,11 @@ private: bool isReturnValue, const Value *V); void VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs, const Value *V); + void VerifyFunctionMetadata( + const SmallVector, 4> MDs); - void VerifyConstantExprBitcastType(const ConstantExpr *CE); + void visitConstantExprsRecursively(const Constant *EntryC); + void visitConstantExpr(const ConstantExpr *CE); void VerifyStatepoint(ImmutableCallSite CS); void verifyFrameRecoverIndices(); @@ -437,9 +461,12 @@ void Verifier::visitGlobalValue(const GlobalValue &GV) { if (GV.hasAppendingLinkage()) { const GlobalVariable *GVar = dyn_cast(&GV); - Assert(GVar && GVar->getType()->getElementType()->isArrayTy(), + Assert(GVar && GVar->getValueType()->isArrayTy(), "Only global arrays can have appending linkage!", GVar); } + + if (GV.isDeclarationForLinker()) + Assert(!GV.hasComdat(), "Declaration may not be in a Comdat!", &GV); } void Verifier::visitGlobalVariable(const GlobalVariable &GV) { @@ -469,7 +496,7 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) { "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 (ArrayType *ATy = dyn_cast(GV.getType()->getElementType())) { + if (ArrayType *ATy = dyn_cast(GV.getValueType())) { StructType *STy = dyn_cast(ATy->getElementType()); PointerType *FuncPtrTy = FunctionType::get(Type::getVoidTy(*Context), false)->getPointerTo(); @@ -492,7 +519,7 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) { GV.getName() == "llvm.compiler.used")) { Assert(!GV.hasInitializer() || GV.hasAppendingLinkage(), "invalid linkage for intrinsic global variable", &GV); - Type *GVType = GV.getType()->getElementType(); + Type *GVType = GV.getValueType(); if (ArrayType *ATy = dyn_cast(GVType)) { PointerType *PTy = dyn_cast(ATy->getElementType()); Assert(PTy, "wrong type for intrinsic global variable", &GV); @@ -523,25 +550,7 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) { } // Walk any aggregate initializers looking for bitcasts between address spaces - SmallPtrSet Visited; - SmallVector WorkStack; - WorkStack.push_back(cast(GV.getInitializer())); - - while (!WorkStack.empty()) { - const Value *V = WorkStack.pop_back_val(); - if (!Visited.insert(V).second) - continue; - - if (const User *U = dyn_cast(V)) { - WorkStack.append(U->op_begin(), U->op_end()); - } - - if (const ConstantExpr *CE = dyn_cast(V)) { - VerifyConstantExprBitcastType(CE); - if (Broken) - return; - } - } + visitConstantExprsRecursively(GV.getInitializer()); visitGlobalValue(GV); } @@ -555,7 +564,8 @@ void Verifier::visitAliaseeSubExpr(const GlobalAlias &GA, const Constant &C) { void Verifier::visitAliaseeSubExpr(SmallPtrSetImpl &Visited, const GlobalAlias &GA, const Constant &C) { if (const auto *GV = dyn_cast(&C)) { - Assert(!GV->isDeclaration(), "Alias must point to a definition", &GA); + Assert(!GV->isDeclarationForLinker(), "Alias must point to a definition", + &GA); if (const auto *GA2 = dyn_cast(GV)) { Assert(Visited.insert(GA2).second, "Aliases cannot form a cycle", &GA); @@ -570,7 +580,7 @@ void Verifier::visitAliaseeSubExpr(SmallPtrSetImpl &Visited, } if (const auto *CE = dyn_cast(&C)) - VerifyConstantExprBitcastType(CE); + visitConstantExprsRecursively(CE); for (const Use &U : C.operands()) { Value *V = &*U; @@ -582,7 +592,6 @@ void Verifier::visitAliaseeSubExpr(SmallPtrSetImpl &Visited, } void Verifier::visitGlobalAlias(const GlobalAlias &GA) { - Assert(!GA.getName().empty(), "Alias name cannot be empty!", &GA); Assert(GlobalAlias::isValidLinkage(GA.getLinkage()), "Alias should have private, internal, linkonce, weak, linkonce_odr, " "weak_odr, or external linkage!", @@ -605,7 +614,7 @@ void Verifier::visitNamedMDNode(const NamedMDNode &NMD) { MDNode *MD = NMD.getOperand(i); if (NMD.getName() == "llvm.dbg.cu") { - Assert(MD && isa(MD), "invalid compile unit", &NMD, MD); + Assert(MD && isa(MD), "invalid compile unit", &NMD, MD); } if (!MD) @@ -711,17 +720,17 @@ bool Verifier::isValidUUID(const MDNode &N, const Metadata *MD) { /// \brief Check if a value can be a reference to a type. bool Verifier::isTypeRef(const MDNode &N, const Metadata *MD) { - return !MD || isValidUUID(N, MD) || isa(MD); + return !MD || isValidUUID(N, MD) || isa(MD); } /// \brief Check if a value can be a ScopeRef. bool Verifier::isScopeRef(const MDNode &N, const Metadata *MD) { - return !MD || isValidUUID(N, MD) || isa(MD); + return !MD || isValidUUID(N, MD) || isa(MD); } /// \brief Check if a value can be a debug info ref. bool Verifier::isDIRef(const MDNode &N, const Metadata *MD) { - return !MD || isValidUUID(N, MD) || isa(MD); + return !MD || isValidUUID(N, MD) || isa(MD); } template @@ -748,69 +757,40 @@ bool isValidMetadataNullArray(const MDTuple &N) { return isValidMetadataArrayImpl(N, /* AllowNull */ true); } -void Verifier::visitMDLocation(const MDLocation &N) { - Assert(N.getRawScope() && isa(N.getRawScope()), +void Verifier::visitDILocation(const DILocation &N) { + Assert(N.getRawScope() && isa(N.getRawScope()), "location requires a valid scope", &N, N.getRawScope()); if (auto *IA = N.getRawInlinedAt()) - Assert(isa(IA), "inlined-at should be a location", &N, IA); + Assert(isa(IA), "inlined-at should be a location", &N, IA); } -void Verifier::visitGenericDebugNode(const GenericDebugNode &N) { +void Verifier::visitGenericDINode(const GenericDINode &N) { Assert(N.getTag(), "invalid tag", &N); } -void Verifier::visitMDScope(const MDScope &N) { +void Verifier::visitDIScope(const DIScope &N) { if (auto *F = N.getRawFile()) - Assert(isa(F), "invalid file", &N, F); + Assert(isa(F), "invalid file", &N, F); } -void Verifier::visitMDSubrange(const MDSubrange &N) { +void Verifier::visitDISubrange(const DISubrange &N) { Assert(N.getTag() == dwarf::DW_TAG_subrange_type, "invalid tag", &N); Assert(N.getCount() >= -1, "invalid subrange count", &N); } -void Verifier::visitMDEnumerator(const MDEnumerator &N) { +void Verifier::visitDIEnumerator(const DIEnumerator &N) { Assert(N.getTag() == dwarf::DW_TAG_enumerator, "invalid tag", &N); } -void Verifier::visitMDBasicType(const MDBasicType &N) { +void Verifier::visitDIBasicType(const DIBasicType &N) { Assert(N.getTag() == dwarf::DW_TAG_base_type || N.getTag() == dwarf::DW_TAG_unspecified_type, "invalid tag", &N); } -void Verifier::visitMDDerivedTypeBase(const MDDerivedTypeBase &N) { +void Verifier::visitDIDerivedType(const DIDerivedType &N) { // Common scope checks. - visitMDScope(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::visitMDDerivedType(const MDDerivedType &N) { - // Common derived type checks. - visitMDDerivedTypeBase(N); + visitDIScope(N); Assert(N.getTag() == dwarf::DW_TAG_typedef || N.getTag() == dwarf::DW_TAG_pointer_type || @@ -828,47 +808,58 @@ void Verifier::visitMDDerivedType(const MDDerivedType &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) { - return (Flags & DebugNode::FlagLValueReference) && - (Flags & DebugNode::FlagRValueReference); + return (Flags & DINode::FlagLValueReference) && + (Flags & DINode::FlagRValueReference); } void Verifier::visitTemplateParams(const MDNode &N, const Metadata &RawParams) { auto *Params = dyn_cast(&RawParams); Assert(Params, "invalid template params", &N, &RawParams); for (Metadata *Op : Params->operands()) { - Assert(Op && isa(Op), "invalid template parameter", &N, + Assert(Op && isa(Op), "invalid template parameter", &N, Params, Op); } } -void Verifier::visitMDCompositeType(const MDCompositeType &N) { - // Common derived type checks. - visitMDDerivedTypeBase(N); +void Verifier::visitDICompositeType(const DICompositeType &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, N.getRawVTableHolder()); - Assert(!N.getRawElements() || isa(N.getRawElements()), - "invalid composite elements", &N, N.getRawElements()); Assert(!hasConflictingReferenceFlags(N.getFlags()), "invalid reference flags", &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::visitMDSubroutineType(const MDSubroutineType &N) { +void Verifier::visitDISubroutineType(const DISubroutineType &N) { Assert(N.getTag() == dwarf::DW_TAG_subroutine_type, "invalid tag", &N); if (auto *Types = N.getRawTypeArray()) { Assert(isa(Types), "invalid composite elements", &N, Types); @@ -880,24 +871,25 @@ void Verifier::visitMDSubroutineType(const MDSubroutineType &N) { &N); } -void Verifier::visitMDFile(const MDFile &N) { +void Verifier::visitDIFile(const DIFile &N) { Assert(N.getTag() == dwarf::DW_TAG_file_type, "invalid tag", &N); } -void Verifier::visitMDCompileUnit(const MDCompileUnit &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 // as those could be empty. - Assert(N.getRawFile() && isa(N.getRawFile()), - "invalid file", &N, N.getRawFile()); + Assert(N.getRawFile() && isa(N.getRawFile()), "invalid file", &N, + N.getRawFile()); Assert(!N.getFile()->getFilename().empty(), "invalid filename", &N, N.getFile()); if (auto *Array = N.getRawEnumTypes()) { Assert(isa(Array), "invalid enum list", &N, Array); for (Metadata *Op : N.getEnumTypes()->operands()) { - auto *Enum = dyn_cast_or_null(Op); + auto *Enum = dyn_cast_or_null(Op); Assert(Enum && Enum->getTag() == dwarf::DW_TAG_enumeration_type, "invalid enum type", &N, N.getEnumTypes(), Op); } @@ -905,135 +897,128 @@ void Verifier::visitMDCompileUnit(const MDCompileUnit &N) { if (auto *Array = N.getRawRetainedTypes()) { Assert(isa(Array), "invalid retained type list", &N, Array); for (Metadata *Op : N.getRetainedTypes()->operands()) { - Assert(Op && isa(Op), "invalid retained type", &N, Op); + Assert(Op && isa(Op), "invalid retained type", &N, Op); } } if (auto *Array = N.getRawSubprograms()) { Assert(isa(Array), "invalid subprogram list", &N, Array); for (Metadata *Op : N.getSubprograms()->operands()) { - Assert(Op && isa(Op), "invalid subprogram ref", &N, Op); + Assert(Op && isa(Op), "invalid subprogram ref", &N, Op); } } if (auto *Array = N.getRawGlobalVariables()) { Assert(isa(Array), "invalid global variable list", &N, Array); for (Metadata *Op : N.getGlobalVariables()->operands()) { - Assert(Op && isa(Op), "invalid global variable ref", &N, + Assert(Op && isa(Op), "invalid global variable ref", &N, Op); } } if (auto *Array = N.getRawImportedEntities()) { Assert(isa(Array), "invalid imported entity list", &N, Array); for (Metadata *Op : N.getImportedEntities()->operands()) { - Assert(Op && isa(Op), "invalid imported entity ref", &N, + Assert(Op && isa(Op), "invalid imported entity ref", &N, Op); } } + if (auto *Array = N.getRawMacros()) { + Assert(isa(Array), "invalid macro list", &N, Array); + for (Metadata *Op : N.getMacros()->operands()) { + Assert(Op && isa(Op), "invalid macro ref", &N, Op); + } + } } -void Verifier::visitMDSubprogram(const MDSubprogram &N) { +void Verifier::visitDISubprogram(const DISubprogram &N) { Assert(N.getTag() == dwarf::DW_TAG_subprogram, "invalid tag", &N); Assert(isScopeRef(N, N.getRawScope()), "invalid scope", &N, N.getRawScope()); if (auto *T = N.getRawType()) - Assert(isa(T), "invalid subroutine type", &N, T); + Assert(isa(T), "invalid subroutine type", &N, T); Assert(isTypeRef(N, N.getRawContainingType()), "invalid containing type", &N, N.getRawContainingType()); - if (auto *RawF = N.getRawFunction()) { - auto *FMD = dyn_cast(RawF); - auto *F = FMD ? FMD->getValue() : nullptr; - auto *FT = F ? dyn_cast(F->getType()) : nullptr; - Assert(F && FT && isa(FT->getElementType()), - "invalid function", &N, F, FT); - } if (auto *Params = N.getRawTemplateParams()) visitTemplateParams(N, *Params); if (auto *S = N.getRawDeclaration()) { - Assert(isa(S) && !cast(S)->isDefinition(), + Assert(isa(S) && !cast(S)->isDefinition(), "invalid subprogram declaration", &N, S); } if (auto *RawVars = N.getRawVariables()) { auto *Vars = dyn_cast(RawVars); Assert(Vars, "invalid variable list", &N, RawVars); for (Metadata *Op : Vars->operands()) { - Assert(Op && isa(Op), "invalid local variable", &N, Vars, + Assert(Op && isa(Op), "invalid local variable", &N, Vars, Op); } } Assert(!hasConflictingReferenceFlags(N.getFlags()), "invalid reference flags", &N); - auto *F = N.getFunction(); - if (!F) - return; - - // Check that all !dbg attachments lead to back to N (or, at least, another - // subprogram that describes the same function). - // - // FIXME: Check this incrementally while visiting !dbg attachments. - // FIXME: Only check when N is the canonical subprogram for F. - SmallPtrSet Seen; - for (auto &BB : *F) - for (auto &I : BB) { - // Be careful about using MDLocation here since we might be dealing with - // broken code (this is the Verifier after all). - MDLocation *DL = - dyn_cast_or_null(I.getDebugLoc().getAsMDNode()); - if (!DL) - continue; - if (!Seen.insert(DL).second) - continue; - - MDLocalScope *Scope = DL->getInlinedAtScope(); - if (Scope && !Seen.insert(Scope).second) - continue; - - MDSubprogram *SP = Scope ? Scope->getSubprogram() : nullptr; - if (SP && !Seen.insert(SP).second) - continue; - - // FIXME: Once N is canonical, check "SP == &N". - Assert(SP->describes(F), - "!dbg attachment points at wrong subprogram for function", &N, F, - &I, DL, Scope, SP); - } + if (N.isDefinition()) + Assert(N.isDistinct(), "subprogram definitions must be distinct", &N); } -void Verifier::visitMDLexicalBlockBase(const MDLexicalBlockBase &N) { +void Verifier::visitDILexicalBlockBase(const DILexicalBlockBase &N) { Assert(N.getTag() == dwarf::DW_TAG_lexical_block, "invalid tag", &N); - Assert(N.getRawScope() && isa(N.getRawScope()), + Assert(N.getRawScope() && isa(N.getRawScope()), "invalid local scope", &N, N.getRawScope()); } -void Verifier::visitMDLexicalBlock(const MDLexicalBlock &N) { - visitMDLexicalBlockBase(N); +void Verifier::visitDILexicalBlock(const DILexicalBlock &N) { + visitDILexicalBlockBase(N); Assert(N.getLine() || !N.getColumn(), "cannot have column info without line info", &N); } -void Verifier::visitMDLexicalBlockFile(const MDLexicalBlockFile &N) { - visitMDLexicalBlockBase(N); +void Verifier::visitDILexicalBlockFile(const DILexicalBlockFile &N) { + visitDILexicalBlockBase(N); } -void Verifier::visitMDNamespace(const MDNamespace &N) { +void Verifier::visitDINamespace(const DINamespace &N) { Assert(N.getTag() == dwarf::DW_TAG_namespace, "invalid tag", &N); if (auto *S = N.getRawScope()) - Assert(isa(S), "invalid scope ref", &N, S); + Assert(isa(S), "invalid scope ref", &N, S); +} + +void Verifier::visitDIMacro(const DIMacro &N) { + Assert(N.getMacinfoType() == dwarf::DW_MACINFO_define || + N.getMacinfoType() == dwarf::DW_MACINFO_undef, + "invalid macinfo type", &N); + Assert(!N.getName().empty(), "anonymous macro", &N); } -void Verifier::visitMDTemplateParameter(const MDTemplateParameter &N) { +void Verifier::visitDIMacroFile(const DIMacroFile &N) { + Assert(N.getMacinfoType() == dwarf::DW_MACINFO_start_file, + "invalid macinfo type", &N); + if (auto *F = N.getRawFile()) + Assert(isa(F), "invalid file", &N, F); + + if (auto *Array = N.getRawElements()) { + Assert(isa(Array), "invalid macro list", &N, Array); + for (Metadata *Op : N.getElements()->operands()) { + Assert(Op && isa(Op), "invalid macro ref", &N, Op); + } + } +} + +void Verifier::visitDIModule(const DIModule &N) { + Assert(N.getTag() == dwarf::DW_TAG_module, "invalid tag", &N); + Assert(!N.getName().empty(), "anonymous module", &N); +} + +void Verifier::visitDITemplateParameter(const DITemplateParameter &N) { Assert(isTypeRef(N, N.getType()), "invalid type ref", &N, N.getType()); } -void Verifier::visitMDTemplateTypeParameter(const MDTemplateTypeParameter &N) { - visitMDTemplateParameter(N); +void Verifier::visitDITemplateTypeParameter(const DITemplateTypeParameter &N) { + visitDITemplateParameter(N); Assert(N.getTag() == dwarf::DW_TAG_template_type_parameter, "invalid tag", &N); } -void Verifier::visitMDTemplateValueParameter( - const MDTemplateValueParameter &N) { - visitMDTemplateParameter(N); +void Verifier::visitDITemplateValueParameter( + const DITemplateValueParameter &N) { + visitDITemplateParameter(N); Assert(N.getTag() == dwarf::DW_TAG_template_value_parameter || N.getTag() == dwarf::DW_TAG_GNU_template_template_param || @@ -1041,17 +1026,17 @@ void Verifier::visitMDTemplateValueParameter( "invalid tag", &N); } -void Verifier::visitMDVariable(const MDVariable &N) { +void Verifier::visitDIVariable(const DIVariable &N) { if (auto *S = N.getRawScope()) - Assert(isa(S), "invalid scope", &N, S); + Assert(isa(S), "invalid scope", &N, S); Assert(isTypeRef(N, N.getRawType()), "invalid type ref", &N, N.getRawType()); if (auto *F = N.getRawFile()) - Assert(isa(F), "invalid file", &N, F); + Assert(isa(F), "invalid file", &N, F); } -void Verifier::visitMDGlobalVariable(const MDGlobalVariable &N) { +void Verifier::visitDIGlobalVariable(const DIGlobalVariable &N) { // Checks common to all variables. - visitMDVariable(N); + visitDIVariable(N); Assert(N.getTag() == dwarf::DW_TAG_variable, "invalid tag", &N); Assert(!N.getName().empty(), "missing global variable name", &N); @@ -1061,40 +1046,38 @@ void Verifier::visitMDGlobalVariable(const MDGlobalVariable &N) { "invalid global varaible ref", &N, V); } if (auto *Member = N.getRawStaticDataMemberDeclaration()) { - Assert(isa(Member), "invalid static data member declaration", + Assert(isa(Member), "invalid static data member declaration", &N, Member); } } -void Verifier::visitMDLocalVariable(const MDLocalVariable &N) { +void Verifier::visitDILocalVariable(const DILocalVariable &N) { // Checks common to all variables. - visitMDVariable(N); + visitDIVariable(N); - Assert(N.getTag() == dwarf::DW_TAG_auto_variable || - N.getTag() == dwarf::DW_TAG_arg_variable, - "invalid tag", &N); - Assert(N.getRawScope() && isa(N.getRawScope()), + 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()); } -void Verifier::visitMDExpression(const MDExpression &N) { +void Verifier::visitDIExpression(const DIExpression &N) { Assert(N.isValid(), "invalid expression", &N); } -void Verifier::visitMDObjCProperty(const MDObjCProperty &N) { +void Verifier::visitDIObjCProperty(const DIObjCProperty &N) { Assert(N.getTag() == dwarf::DW_TAG_APPLE_property, "invalid tag", &N); if (auto *T = N.getRawType()) - Assert(isa(T), "invalid type ref", &N, T); + Assert(isTypeRef(N, T), "invalid type ref", &N, T); if (auto *F = N.getRawFile()) - Assert(isa(F), "invalid file", &N, F); + Assert(isa(F), "invalid file", &N, F); } -void Verifier::visitMDImportedEntity(const MDImportedEntity &N) { +void Verifier::visitDIImportedEntity(const DIImportedEntity &N) { Assert(N.getTag() == dwarf::DW_TAG_imported_module || N.getTag() == dwarf::DW_TAG_imported_declaration, "invalid tag", &N); if (auto *S = N.getRawScope()) - Assert(isa(S), "invalid scope for imported entity", &N, S); + Assert(isa(S), "invalid scope for imported entity", &N, S); Assert(isDIRef(N, N.getEntity()), "invalid imported entity", &N, N.getEntity()); } @@ -1249,6 +1232,7 @@ void Verifier::VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx, I->getKindAsEnum() == Attribute::StackProtect || I->getKindAsEnum() == Attribute::StackProtectReq || I->getKindAsEnum() == Attribute::StackProtectStrong || + I->getKindAsEnum() == Attribute::SafeStack || I->getKindAsEnum() == Attribute::NoRedZone || I->getKindAsEnum() == Attribute::NoImplicitFloat || I->getKindAsEnum() == Attribute::Naked || @@ -1266,7 +1250,12 @@ void Verifier::VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx, I->getKindAsEnum() == Attribute::NoBuiltin || I->getKindAsEnum() == Attribute::Cold || I->getKindAsEnum() == Attribute::OptimizeNone || - I->getKindAsEnum() == Attribute::JumpTable) { + I->getKindAsEnum() == Attribute::JumpTable || + I->getKindAsEnum() == Attribute::Convergent || + I->getKindAsEnum() == Attribute::ArgMemOnly || + I->getKindAsEnum() == Attribute::NoRecurse || + I->getKindAsEnum() == Attribute::InaccessibleMemOnly || + I->getKindAsEnum() == Attribute::InaccessibleMemOrArgMemOnly) { if (!isFunction) { CheckFailed("Attribute '" + I->getAsString() + "' only applies to functions!", V); @@ -1350,13 +1339,14 @@ void Verifier::VerifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty, V); Assert(!AttrBuilder(Attrs, Idx) - .hasAttributes(AttributeFuncs::typeIncompatible(Ty, Idx), Idx), + .overlaps(AttributeFuncs::typeIncompatible(Ty)), "Wrong types for attribute: " + - AttributeFuncs::typeIncompatible(Ty, Idx).getAsString(Idx), + AttributeSet::get(*Context, Idx, + AttributeFuncs::typeIncompatible(Ty)).getAsString(Idx), 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), @@ -1435,6 +1425,18 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs, Attrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly)), "Attributes 'readnone and readonly' are incompatible!", V); + Assert( + !(Attrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone) && + Attrs.hasAttribute(AttributeSet::FunctionIndex, + Attribute::InaccessibleMemOrArgMemOnly)), + "Attributes 'readnone and inaccessiblemem_or_argmemonly' are incompatible!", V); + + Assert( + !(Attrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone) && + Attrs.hasAttribute(AttributeSet::FunctionIndex, + Attribute::InaccessibleMemOnly)), + "Attributes 'readnone and inaccessiblememonly' are incompatible!", V); + Assert( !(Attrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::NoInline) && Attrs.hasAttribute(AttributeSet::FunctionIndex, @@ -1462,7 +1464,65 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs, } } -void Verifier::VerifyConstantExprBitcastType(const ConstantExpr *CE) { +void Verifier::VerifyFunctionMetadata( + const SmallVector, 4> MDs) { + if (MDs.empty()) + return; + + for (unsigned i = 0; i < MDs.size(); i++) { + if (MDs[i].first == LLVMContext::MD_prof) { + MDNode *MD = MDs[i].second; + Assert(MD->getNumOperands() == 2, + "!prof annotations should have exactly 2 operands", MD); + + // Check first operand. + Assert(MD->getOperand(0) != nullptr, "first operand should not be null", + MD); + Assert(isa(MD->getOperand(0)), + "expected string with name of the !prof annotation", MD); + MDString *MDS = cast(MD->getOperand(0)); + StringRef ProfName = MDS->getString(); + Assert(ProfName.equals("function_entry_count"), + "first operand should be 'function_entry_count'", MD); + + // Check second operand. + Assert(MD->getOperand(1) != nullptr, "second operand should not be null", + MD); + Assert(isa(MD->getOperand(1)), + "expected integer argument to function_entry_count", MD); + } + } +} + +void Verifier::visitConstantExprsRecursively(const Constant *EntryC) { + if (!ConstantExprVisited.insert(EntryC).second) + return; + + SmallVector Stack; + Stack.push_back(EntryC); + + while (!Stack.empty()) { + const Constant *C = Stack.pop_back_val(); + + // Check this constant expression. + if (const auto *CE = dyn_cast(C)) + visitConstantExpr(CE); + + // Visit all sub-expressions. + for (const Use &U : C->operands()) { + const auto *OpC = dyn_cast(U); + if (!OpC) + continue; + if (isa(OpC)) + continue; // Global values get visited separately. + if (!ConstantExprVisited.insert(OpC).second) + continue; + Stack.push_back(OpC); + } + } +} + +void Verifier::visitConstantExpr(const ConstantExpr *CE) { if (CE->getOpcode() != Instruction::BitCast) return; @@ -1493,18 +1553,34 @@ 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); - const Value *Target = CS.getArgument(0); - const PointerType *PT = dyn_cast(Target->getType()); + const Value *IDV = CS.getArgument(0); + Assert(isa(IDV), "gc.statepoint ID must be a constant integer", + &CI); + + const Value *NumPatchBytesV = CS.getArgument(1); + Assert(isa(NumPatchBytesV), + "gc.statepoint number of patchable bytes must be a constant integer", + &CI); + const int64_t NumPatchBytes = + cast(NumPatchBytesV)->getSExtValue(); + assert(isInt<32>(NumPatchBytes) && "NumPatchBytesV is an i32!"); + Assert(NumPatchBytes >= 0, "gc.statepoint number of patchable bytes must be " + "positive", + &CI); + + const Value *Target = CS.getArgument(2); + 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()); - const Value *NumCallArgsV = CS.getArgument(1); + const Value *NumCallArgsV = CS.getArgument(3); Assert(isa(NumCallArgsV), "gc.statepoint number of arguments to underlying call " "must be constant integer", @@ -1528,22 +1604,38 @@ void Verifier::VerifyStatepoint(ImmutableCallSite CS) { Assert(NumCallArgs == NumParams, "gc.statepoint mismatch in number of call args", &CI); - const Value *Unused = CS.getArgument(2); - Assert(isa(Unused) && cast(Unused)->isNullValue(), - "gc.statepoint parameter #3 must be zero", &CI); + const Value *FlagsV = CS.getArgument(4); + Assert(isa(FlagsV), + "gc.statepoint flags must be constant integer", &CI); + const uint64_t Flags = cast(FlagsV)->getZExtValue(); + Assert((Flags & ~(uint64_t)StatepointFlags::MaskAll) == 0, + "unknown flag used in gc.statepoint flags argument", &CI); // Verify that the types of the call parameter arguments match // the type of the wrapped callee. for (int i = 0; i < NumParams; i++) { Type *ParamType = TargetFuncType->getParamType(i); - Type *ArgType = CS.getArgument(3+i)->getType(); + Type *ArgType = CS.getArgument(5 + i)->getType(); Assert(ArgType == ParamType, "gc.statepoint call argument does not match wrapped " "function type", &CI); } - const int EndCallArgsInx = 2+NumCallArgs; - const Value *NumDeoptArgsV = CS.getArgument(EndCallArgsInx+1); + + const int EndCallArgsInx = 4 + NumCallArgs; + + const Value *NumTransitionArgsV = CS.getArgument(EndCallArgsInx+1); + Assert(isa(NumTransitionArgsV), + "gc.statepoint number of transition arguments " + "must be constant integer", + &CI); + const int NumTransitionArgs = + cast(NumTransitionArgsV)->getZExtValue(); + Assert(NumTransitionArgs >= 0, + "gc.statepoint number of transition arguments must be positive", &CI); + const int EndTransitionArgsInx = EndCallArgsInx + 1 + NumTransitionArgs; + + const Value *NumDeoptArgsV = CS.getArgument(EndTransitionArgsInx+1); Assert(isa(NumDeoptArgsV), "gc.statepoint number of deoptimization arguments " "must be constant integer", @@ -1553,7 +1645,9 @@ void Verifier::VerifyStatepoint(ImmutableCallSite CS) { "must be positive", &CI); - Assert(4 + NumCallArgs + NumDeoptArgs <= (int)CS.arg_size(), + const int ExpectedNumArgs = + 7 + NumCallArgs + NumTransitionArgs + NumDeoptArgs; + Assert(ExpectedNumArgs <= (int)CS.arg_size(), "gc.statepoint too few arguments according to length fields", &CI); // Check that the only uses of this gc.statepoint are gc.result or @@ -1592,8 +1686,8 @@ void Verifier::verifyFrameRecoverIndices() { unsigned EscapedObjectCount = Counts.second.first; unsigned MaxRecoveredIndex = Counts.second.second; Assert(MaxRecoveredIndex <= EscapedObjectCount, - "all indices passed to llvm.framerecover must be less than the " - "number of arguments passed ot llvm.frameescape in the parent " + "all indices passed to llvm.localrecover must be less than the " + "number of arguments passed ot llvm.localescape in the parent " "function", F); } @@ -1664,16 +1758,44 @@ 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); + assert(F.hasMetadata() != MDs.empty() && "Bit out-of-sync"); + VerifyFunctionMetadata(MDs); + + // Check validity of the personality function + if (F.hasPersonalityFn()) { + auto *Per = dyn_cast(F.getPersonalityFn()->stripPointerCasts()); + if (Per) + Assert(Per->getParent() == F.getParent(), + "Referencing personality function in another module!", + &F, F.getParent(), Per, Per->getParent()); } if (F.isMaterializable()) { // Function has a body somewhere we can't see. + Assert(MDs.empty(), "unmaterialized function cannot have metadata", &F, + MDs.empty() ? nullptr : MDs.front().second); } else if (F.isDeclaration()) { Assert(F.hasExternalLinkage() || F.hasExternalWeakLinkage(), "invalid linkage type for function declaration", &F); + Assert(MDs.empty(), "function without a body cannot have metadata", &F, + MDs.empty() ? nullptr : MDs.front().second); + Assert(!F.hasPersonalityFn(), + "Function declaration shouldn't have a personality routine", &F); } else { // Verify that this function (which has a body) is not named "llvm.*". It // is not legal to define intrinsics. @@ -1689,6 +1811,22 @@ void Verifier::visitFunction(const Function &F) { Assert(!BlockAddress::lookup(Entry)->isConstantUsed(), "blockaddress may not be used with the entry block!", Entry); } + + // Visit metadata attachments. + 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 @@ -1703,6 +1841,44 @@ void Verifier::visitFunction(const Function &F) { (F.isDeclaration() && F.hasExternalLinkage()) || F.hasAvailableExternallyLinkage(), "Function is marked as dllimport, but not external.", &F); + + auto *N = F.getSubprogram(); + if (!N) + return; + + // Check that all !dbg attachments lead to back to N (or, at least, another + // subprogram that describes the same function). + // + // FIXME: Check this incrementally while visiting !dbg attachments. + // FIXME: Only check when N is the canonical subprogram for F. + SmallPtrSet Seen; + for (auto &BB : F) + for (auto &I : BB) { + // Be careful about using DILocation here since we might be dealing with + // broken code (this is the Verifier after all). + DILocation *DL = + dyn_cast_or_null(I.getDebugLoc().getAsMDNode()); + if (!DL) + continue; + if (!Seen.insert(DL).second) + continue; + + DILocalScope *Scope = DL->getInlinedAtScope(); + if (Scope && !Seen.insert(Scope).second) + continue; + + DISubprogram *SP = Scope ? Scope->getSubprogram() : nullptr; + + // Scope and SP could be the same MDNode and we don't want to skip + // validation in that case + if (SP && ((Scope != SP) && !Seen.insert(SP).second)) + continue; + + // FIXME: Once N is canonical, check "SP == &N". + Assert(SP->describes(&F), + "!dbg attachment points at wrong subprogram for function", N, &F, + &I, DL, Scope, SP); + } } // verifyBasicBlock - Verify that a basic block is well formed... @@ -2099,10 +2275,13 @@ 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 (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) { - Assert(PN.getType() == PN.getIncomingValue(i)->getType(), + for (Value *IncValue : PN.incoming_values()) { + Assert(PN.getType() == IncValue->getType(), "PHI node operands are not the same type as the result!", &PN); } @@ -2120,7 +2299,11 @@ void Verifier::VerifyCallSite(CallSite CS) { Assert(FPTy->getElementType()->isFunctionTy(), "Called function is not pointer to function type!", I); - FunctionType *FTy = cast(FPTy->getElementType()); + + Assert(FPTy->getElementType() == CS.getFunctionType(), + "Called function is not the same type as the call!", I); + + FunctionType *FTy = CS.getFunctionType(); // Verify that the correct number of arguments are being passed if (FTy->isVarArg()) @@ -2197,10 +2380,42 @@ 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); + + // Verify that a callsite has at most one "deopt" and one "funclet" operand + // bundle. + bool FoundDeoptBundle = false, FoundFuncletBundle = false; + for (unsigned i = 0, e = CS.getNumOperandBundles(); i < e; ++i) { + OperandBundleUse BU = CS.getOperandBundleAt(i); + uint32_t Tag = BU.getTagID(); + if (Tag == LLVMContext::OB_deopt) { + Assert(!FoundDeoptBundle, "Multiple deopt operand bundles", I); + FoundDeoptBundle = true; + } + if (Tag == LLVMContext::OB_funclet) { + Assert(!FoundFuncletBundle, "Multiple funclet operand bundles", I); + FoundFuncletBundle = true; + Assert(BU.Inputs.size() == 1, + "Expected exactly one funclet bundle operand", I); + Assert(isa(BU.Inputs.front()), + "Funclet bundle operands should correspond to a FuncletPadInst", + I); + } } visitInstruction(*I); @@ -2239,12 +2454,8 @@ void Verifier::verifyMustTailCall(CallInst &CI) { // parameters or return types may differ in pointee type, but not // address space. Function *F = CI.getParent()->getParent(); - auto GetFnTy = [](Value *V) { - return cast( - cast(V->getType())->getElementType()); - }; - FunctionType *CallerTy = GetFnTy(F); - FunctionType *CalleeTy = GetFnTy(CI.getCalledValue()); + FunctionType *CallerTy = F->getFunctionType(); + FunctionType *CalleeTy = CI.getFunctionType(); Assert(CallerTy->getNumParams() == CalleeTy->getNumParams(), "cannot guarantee tail call due to mismatched parameter counts", &CI); Assert(CallerTy->isVarArg() == CalleeTy->isVarArg(), @@ -2302,26 +2513,17 @@ void Verifier::visitCallInst(CallInst &CI) { if (CI.isMustTailCall()) verifyMustTailCall(CI); - - if (Function *F = CI.getCalledFunction()) - if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID()) - visitIntrinsicFunctionCall(ID, CI); } void Verifier::visitInvokeInst(InvokeInst &II) { VerifyCallSite(&II); - // Verify that there is a landingpad instruction as the first non-PHI - // instruction of the 'unwind' destination. - Assert(II.getUnwindDest()->isLandingPad(), - "The unwind destination does not have a landingpad instruction!", &II); - - if (Function *F = II.getCalledFunction()) - // TODO: Ideally we should use visitIntrinsicFunction here. But it uses - // CallInst as an input parameter. It not woth updating this whole - // function only to support statepoint verification. - if (F->getIntrinsicID() == Intrinsic::experimental_gc_statepoint) - VerifyStatepoint(ImmutableCallSite(&II)); + // Verify that the first non-PHI instruction of the unwind destination is an + // exception handling instruction. + Assert( + II.getUnwindDest()->isEHPad(), + "The unwind destination does not have an exception handling instruction!", + &II); visitTerminatorInst(II); } @@ -2452,10 +2654,6 @@ void Verifier::visitGetElementPtrInst(GetElementPtrInst &GEP) { Assert(isa(TargetTy), "GEP base pointer is not a vector or a vector of pointers", &GEP); Assert(GEP.getSourceElementType()->isSized(), "GEP into unsized type!", &GEP); - Assert(GEP.getPointerOperandType()->isVectorTy() == - GEP.getType()->isVectorTy(), - "Vector GEP must return a vector value", &GEP); - SmallVector Idxs(GEP.idx_begin(), GEP.idx_end()); Type *ElTy = GetElementPtrInst::getIndexedType(GEP.getSourceElementType(), Idxs); @@ -2465,17 +2663,20 @@ void Verifier::visitGetElementPtrInst(GetElementPtrInst &GEP) { GEP.getResultElementType() == ElTy, "GEP is not of right type for indices!", &GEP, ElTy); - if (GEP.getPointerOperandType()->isVectorTy()) { + if (GEP.getType()->isVectorTy()) { // Additional checks for vector GEPs. - unsigned GepWidth = GEP.getPointerOperandType()->getVectorNumElements(); - Assert(GepWidth == GEP.getType()->getVectorNumElements(), - "Vector GEP result width doesn't match operand's", &GEP); + unsigned GEPWidth = GEP.getType()->getVectorNumElements(); + if (GEP.getPointerOperandType()->isVectorTy()) + Assert(GEPWidth == GEP.getPointerOperandType()->getVectorNumElements(), + "Vector GEP result width doesn't match operand's", &GEP); for (unsigned i = 0, e = Idxs.size(); i != e; ++i) { Type *IndexTy = Idxs[i]->getType(); - Assert(IndexTy->isVectorTy(), "Vector GEP must have vector indices!", - &GEP); - unsigned IndexWidth = IndexTy->getVectorNumElements(); - Assert(IndexWidth == GepWidth, "Invalid GEP index vector width", &GEP); + if (IndexTy->isVectorTy()) { + unsigned IndexWidth = IndexTy->getVectorNumElements(); + Assert(IndexWidth == GEPWidth, "Invalid GEP index vector width", &GEP); + } + Assert(IndexTy->getScalarType()->isIntegerTy(), + "All GEP indices should be of integer type"); } } visitInstruction(GEP); @@ -2535,6 +2736,14 @@ void Verifier::visitRangeMetadata(Instruction& I, } } +void Verifier::checkAtomicMemAccessSize(const Module *M, Type *Ty, + const Instruction *I) { + unsigned Size = M->getDataLayout().getTypeSizeInBits(Ty); + Assert(Size >= 8, "atomic memory access' size must be byte-sized", Ty, I); + Assert(!(Size & (Size - 1)), + "atomic memory access' operand must have a power-of-two size", Ty, I); +} + void Verifier::visitLoadInst(LoadInst &LI) { PointerType *PTy = dyn_cast(LI.getOperand(0)->getType()); Assert(PTy, "Load operand must be a pointer.", &LI); @@ -2546,14 +2755,12 @@ void Verifier::visitLoadInst(LoadInst &LI) { "Load cannot have Release ordering", &LI); Assert(LI.getAlignment() != 0, "Atomic load must specify explicit alignment", &LI); - if (!ElTy->isPointerTy()) { - Assert(ElTy->isIntegerTy(), "atomic load operand must have integer type!", - &LI, ElTy); - unsigned Size = ElTy->getPrimitiveSizeInBits(); - Assert(Size >= 8 && !(Size & (Size - 1)), - "atomic load operand must be power-of-two byte-sized integer", &LI, - ElTy); - } + Assert(ElTy->isIntegerTy() || ElTy->isPointerTy() || + ElTy->isFloatingPointTy(), + "atomic load operand must have integer, pointer, or floating point " + "type!", + ElTy, &LI); + checkAtomicMemAccessSize(M, ElTy, &LI); } else { Assert(LI.getSynchScope() == CrossThread, "Non-atomic load cannot have SynchronizationScope specified", &LI); @@ -2575,14 +2782,12 @@ void Verifier::visitStoreInst(StoreInst &SI) { "Store cannot have Acquire ordering", &SI); Assert(SI.getAlignment() != 0, "Atomic store must specify explicit alignment", &SI); - if (!ElTy->isPointerTy()) { - Assert(ElTy->isIntegerTy(), - "atomic store operand must have integer type!", &SI, ElTy); - unsigned Size = ElTy->getPrimitiveSizeInBits(); - Assert(Size >= 8 && !(Size & (Size - 1)), - "atomic store operand must be power-of-two byte-sized integer", - &SI, ElTy); - } + Assert(ElTy->isIntegerTy() || ElTy->isPointerTy() || + ElTy->isFloatingPointTy(), + "atomic store operand must have integer, pointer, or floating point " + "type!", + ElTy, &SI); + checkAtomicMemAccessSize(M, ElTy, &SI); } else { Assert(SI.getSynchScope() == CrossThread, "Non-atomic store cannot have SynchronizationScope specified", &SI); @@ -2591,12 +2796,12 @@ 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!", &AI); - Assert(PTy->getElementType()->isSized(&Visited), + Assert(AI.getAllocatedType()->isSized(&Visited), "Cannot allocate unsized type", &AI); Assert(AI.getArraySize()->getType()->isIntegerTy(), "Alloca array size must have integer type", &AI); @@ -2629,9 +2834,7 @@ void Verifier::visitAtomicCmpXchgInst(AtomicCmpXchgInst &CXI) { Type *ElTy = PTy->getElementType(); Assert(ElTy->isIntegerTy(), "cmpxchg operand must have integer type!", &CXI, ElTy); - unsigned Size = ElTy->getPrimitiveSizeInBits(); - Assert(Size >= 8 && !(Size & (Size - 1)), - "cmpxchg operand must be power-of-two byte-sized integer", &CXI, ElTy); + checkAtomicMemAccessSize(M, ElTy, &CXI); Assert(ElTy == CXI.getOperand(1)->getType(), "Expected value type does not match pointer operand type!", &CXI, ElTy); @@ -2650,10 +2853,7 @@ void Verifier::visitAtomicRMWInst(AtomicRMWInst &RMWI) { Type *ElTy = PTy->getElementType(); Assert(ElTy->isIntegerTy(), "atomicrmw operand must have integer type!", &RMWI, ElTy); - unsigned Size = ElTy->getPrimitiveSizeInBits(); - Assert(Size >= 8 && !(Size & (Size - 1)), - "atomicrmw operand must be power-of-two byte-sized integer", &RMWI, - ElTy); + checkAtomicMemAccessSize(M, ElTy, &RMWI); Assert(ElTy == RMWI.getOperand(1)->getType(), "Argument value type does not match pointer operand type!", &RMWI, ElTy); @@ -2690,23 +2890,66 @@ 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; + } + if (auto *CPI = dyn_cast(&I)) { + if (!pred_empty(BB)) + Assert(BB->getUniquePredecessor() == CPI->getCatchSwitch()->getParent(), + "Block containg CatchPadInst must be jumped to " + "only by its catchswitch.", + CPI); + 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 (!isa(TI) && !isa(TI)) { + 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(), + "LandingPadInst needs to be in a function with a personality.", &LPI); // The landingpad instruction must be the first non-PHI instruction in the // block. @@ -2714,16 +2957,6 @@ void Verifier::visitLandingPadInst(LandingPadInst &LPI) { "LandingPadInst not the first non-PHI instruction in the block.", &LPI); - // The personality functions for all landingpad instructions within the same - // function should match. - if (PersonalityFn) - Assert(LPI.getPersonalityFn() == PersonalityFn, - "Personality function doesn't match others in function", &LPI); - PersonalityFn = LPI.getPersonalityFn(); - - // All operands must be constants. - Assert(isa(PersonalityFn), "Personality function is not constant!", - &LPI); for (unsigned i = 0, e = LPI.getNumClauses(); i < e; ++i) { Constant *Clause = LPI.getClause(i); if (LPI.isCatch(i)) { @@ -2739,6 +2972,132 @@ void Verifier::visitLandingPadInst(LandingPadInst &LPI) { visitInstruction(LPI); } +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); + + Assert(isa(CPI.getParentPad()), + "CatchPadInst needs to be directly nested in a CatchSwitchInst.", + CPI.getParentPad()); + + // 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); + + visitInstruction(CPI); +} + +void Verifier::visitCatchReturnInst(CatchReturnInst &CatchReturn) { + Assert(isa(CatchReturn.getOperand(0)), + "CatchReturnInst needs to be provided a CatchPad", &CatchReturn, + CatchReturn.getOperand(0)); + + visitTerminatorInst(CatchReturn); +} + +void Verifier::visitCleanupPadInst(CleanupPadInst &CPI) { + visitEHPadPredecessors(CPI); + + BasicBlock *BB = CPI.getParent(); + + Function *F = BB->getParent(); + Assert(F->hasPersonalityFn(), + "CleanupPadInst needs to be in a function with a personality.", &CPI); + + // The cleanuppad instruction must be the first non-PHI instruction in the + // block. + Assert(BB->getFirstNonPHI() == &CPI, + "CleanupPadInst not the first non-PHI instruction in the block.", + &CPI); + + auto *ParentPad = CPI.getParentPad(); + Assert(isa(ParentPad) || isa(ParentPad) || + isa(ParentPad) || isa(ParentPad), + "CleanupPadInst has an invalid parent.", &CPI); + + User *FirstUser = nullptr; + BasicBlock *FirstUnwindDest = nullptr; + for (User *U : CPI.users()) { + BasicBlock *UnwindDest; + if (CleanupReturnInst *CRI = dyn_cast(U)) { + UnwindDest = CRI->getUnwindDest(); + } else if (isa(U) || isa(U)) { + continue; + } else if (CallSite(U)) { + continue; + } else { + Assert(false, "bogus cleanuppad use", &CPI); + } + + if (!FirstUser) { + FirstUser = U; + FirstUnwindDest = UnwindDest; + } else { + Assert( + UnwindDest == FirstUnwindDest, + "cleanupret instructions from the same cleanuppad must have the same " + "unwind destination", + FirstUser, U); + } + } + + visitInstruction(CPI); +} + +void Verifier::visitCatchSwitchInst(CatchSwitchInst &CatchSwitch) { + visitEHPadPredecessors(CatchSwitch); + + BasicBlock *BB = CatchSwitch.getParent(); + + Function *F = BB->getParent(); + Assert(F->hasPersonalityFn(), + "CatchSwitchInst needs to be in a function with a personality.", + &CatchSwitch); + + // The catchswitch instruction must be the first non-PHI instruction in the + // block. + Assert(BB->getFirstNonPHI() == &CatchSwitch, + "CatchSwitchInst not the first non-PHI instruction in the block.", + &CatchSwitch); + + if (BasicBlock *UnwindDest = CatchSwitch.getUnwindDest()) { + Instruction *I = UnwindDest->getFirstNonPHI(); + Assert(I->isEHPad() && !isa(I), + "CatchSwitchInst must unwind to an EH block which is not a " + "landingpad.", + &CatchSwitch); + } + + auto *ParentPad = CatchSwitch.getParentPad(); + Assert(isa(ParentPad) || isa(ParentPad) || + isa(ParentPad) || isa(ParentPad), + "CatchSwitchInst has an invalid parent.", ParentPad); + + visitTerminatorInst(CatchSwitch); +} + +void Verifier::visitCleanupReturnInst(CleanupReturnInst &CRI) { + Assert(isa(CRI.getOperand(0)), + "CleanupReturnInst needs to be provided a CleanupPad", &CRI, + CRI.getOperand(0)); + + 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); + } + + visitTerminatorInst(CRI); +} + void Verifier::verifyDominatesUse(Instruction &I, unsigned i) { Instruction *Op = cast(I.getOperand(i)); // If the we have an invalid invoke, don't try to compute the dominance. @@ -2754,6 +3113,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) { @@ -2822,7 +3194,7 @@ void Verifier::visitInstruction(Instruction &I) { " donothing or patchpoint", &I); Assert(F->getParent() == M, "Referencing function in another module!", - &I); + &I, M, F, F->getParent()); } else if (BasicBlock *OpBB = dyn_cast(I.getOperand(i))) { Assert(OpBB->getParent() == BB->getParent(), "Referring to a basic block in another function!", &I); @@ -2830,7 +3202,7 @@ void Verifier::visitInstruction(Instruction &I) { Assert(OpArg->getParent() == BB->getParent(), "Referring to an argument in another function!", &I); } else if (GlobalValue *GV = dyn_cast(I.getOperand(i))) { - Assert(GV->getParent() == M, "Referencing global in another module!", &I); + Assert(GV->getParent() == M, "Referencing global in another module!", &I, M, GV, GV->getParent()); } else if (isa(I.getOperand(i))) { verifyDominatesUse(I, i); } else if (isa(I.getOperand(i))) { @@ -2841,22 +3213,7 @@ void Verifier::visitInstruction(Instruction &I) { if (CE->getType()->isPtrOrPtrVectorTy()) { // If we have a ConstantExpr pointer, we need to see if it came from an // illegal bitcast (inttoptr ) - SmallVector Stack; - SmallPtrSet Visited; - Stack.push_back(CE); - - while (!Stack.empty()) { - const ConstantExpr *V = Stack.pop_back_val(); - if (!Visited.insert(V).second) - continue; - - VerifyConstantExprBitcastType(V); - - for (unsigned I = 0, N = V->getNumOperands(); I != N; ++I) { - if (ConstantExpr *Op = dyn_cast(V->getOperand(I))) - Stack.push_back(Op); - } - } + visitConstantExprsRecursively(CE); } } } @@ -2890,8 +3247,30 @@ 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); + Assert(isa(N), "invalid !dbg metadata attachment", &I, N); visitMDNode(*N); } @@ -2917,6 +3296,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(); @@ -3034,8 +3414,8 @@ bool Verifier::VerifyIntrinsicType(Type *Ty, dyn_cast(ThisArgVecTy->getVectorElementType()); if (!ThisArgEltTy) return true; - return (!(ThisArgEltTy->getElementType() == - ReferenceType->getVectorElementType())); + return ThisArgEltTy->getElementType() != + ReferenceType->getVectorElementType(); } } llvm_unreachable("unhandled"); @@ -3068,10 +3448,9 @@ Verifier::VerifyIntrinsicIsVarArg(bool isVarArg, return true; } -/// visitIntrinsicFunction - Allow intrinsics to be verified in different ways. -/// -void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { - Function *IF = CI.getCalledFunction(); +/// Allow intrinsics to be verified in different ways. +void Verifier::visitIntrinsicCallSite(Intrinsic::ID ID, CallSite CS) { + Function *IF = CS.getCalledFunction(); Assert(IF->isDeclaration(), "Intrinsic functions should never be defined!", IF); @@ -3115,41 +3494,41 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { // If the intrinsic takes MDNode arguments, verify that they are either global // or are local to *this* function. - for (unsigned i = 0, e = CI.getNumArgOperands(); i != e; ++i) - if (auto *MD = dyn_cast(CI.getArgOperand(i))) - visitMetadataAsValue(*MD, CI.getParent()->getParent()); + for (Value *V : CS.args()) + if (auto *MD = dyn_cast(V)) + visitMetadataAsValue(*MD, CS.getCaller()); switch (ID) { default: break; case Intrinsic::ctlz: // llvm.ctlz case Intrinsic::cttz: // llvm.cttz - Assert(isa(CI.getArgOperand(1)), + Assert(isa(CS.getArgOperand(1)), "is_zero_undef argument of bit counting intrinsics must be a " "constant int", - &CI); + CS); break; case Intrinsic::dbg_declare: // llvm.dbg.declare - Assert(isa(CI.getArgOperand(0)), - "invalid llvm.dbg.declare intrinsic call 1", &CI); - visitDbgIntrinsic("declare", cast(CI)); + Assert(isa(CS.getArgOperand(0)), + "invalid llvm.dbg.declare intrinsic call 1", CS); + visitDbgIntrinsic("declare", cast(*CS.getInstruction())); break; case Intrinsic::dbg_value: // llvm.dbg.value - visitDbgIntrinsic("value", cast(CI)); + visitDbgIntrinsic("value", cast(*CS.getInstruction())); break; case Intrinsic::memcpy: case Intrinsic::memmove: case Intrinsic::memset: { - ConstantInt *AlignCI = dyn_cast(CI.getArgOperand(3)); + ConstantInt *AlignCI = dyn_cast(CS.getArgOperand(3)); Assert(AlignCI, "alignment argument of memory intrinsics must be a constant int", - &CI); + CS); const APInt &AlignVal = AlignCI->getValue(); Assert(AlignCI->isZero() || AlignVal.isPowerOf2(), - "alignment argument of memory intrinsics must be a power of 2", &CI); - Assert(isa(CI.getArgOperand(4)), + "alignment argument of memory intrinsics must be a power of 2", CS); + Assert(isa(CS.getArgOperand(4)), "isvolatile argument of memory intrinsics must be a constant int", - &CI); + CS); break; } case Intrinsic::gcroot: @@ -3157,76 +3536,76 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { case Intrinsic::gcread: if (ID == Intrinsic::gcroot) { AllocaInst *AI = - dyn_cast(CI.getArgOperand(0)->stripPointerCasts()); - Assert(AI, "llvm.gcroot parameter #1 must be an alloca.", &CI); - Assert(isa(CI.getArgOperand(1)), - "llvm.gcroot parameter #2 must be a constant.", &CI); - if (!AI->getType()->getElementType()->isPointerTy()) { - Assert(!isa(CI.getArgOperand(1)), + dyn_cast(CS.getArgOperand(0)->stripPointerCasts()); + Assert(AI, "llvm.gcroot parameter #1 must be an alloca.", CS); + Assert(isa(CS.getArgOperand(1)), + "llvm.gcroot parameter #2 must be a constant.", CS); + if (!AI->getAllocatedType()->isPointerTy()) { + Assert(!isa(CS.getArgOperand(1)), "llvm.gcroot parameter #1 must either be a pointer alloca, " "or argument #2 must be a non-null constant.", - &CI); + CS); } } - Assert(CI.getParent()->getParent()->hasGC(), - "Enclosing function does not use GC.", &CI); + Assert(CS.getParent()->getParent()->hasGC(), + "Enclosing function does not use GC.", CS); break; case Intrinsic::init_trampoline: - Assert(isa(CI.getArgOperand(1)->stripPointerCasts()), + Assert(isa(CS.getArgOperand(1)->stripPointerCasts()), "llvm.init_trampoline parameter #2 must resolve to a function.", - &CI); + CS); break; case Intrinsic::prefetch: - Assert(isa(CI.getArgOperand(1)) && - isa(CI.getArgOperand(2)) && - cast(CI.getArgOperand(1))->getZExtValue() < 2 && - cast(CI.getArgOperand(2))->getZExtValue() < 4, - "invalid arguments to llvm.prefetch", &CI); + Assert(isa(CS.getArgOperand(1)) && + isa(CS.getArgOperand(2)) && + cast(CS.getArgOperand(1))->getZExtValue() < 2 && + cast(CS.getArgOperand(2))->getZExtValue() < 4, + "invalid arguments to llvm.prefetch", CS); break; case Intrinsic::stackprotector: - Assert(isa(CI.getArgOperand(1)->stripPointerCasts()), - "llvm.stackprotector parameter #2 must resolve to an alloca.", &CI); + Assert(isa(CS.getArgOperand(1)->stripPointerCasts()), + "llvm.stackprotector parameter #2 must resolve to an alloca.", CS); break; case Intrinsic::lifetime_start: case Intrinsic::lifetime_end: case Intrinsic::invariant_start: - Assert(isa(CI.getArgOperand(0)), + Assert(isa(CS.getArgOperand(0)), "size argument of memory use markers must be a constant integer", - &CI); + CS); break; case Intrinsic::invariant_end: - Assert(isa(CI.getArgOperand(1)), - "llvm.invariant.end parameter #2 must be a constant integer", &CI); + Assert(isa(CS.getArgOperand(1)), + "llvm.invariant.end parameter #2 must be a constant integer", CS); break; - case Intrinsic::frameescape: { - BasicBlock *BB = CI.getParent(); + case Intrinsic::localescape: { + BasicBlock *BB = CS.getParent(); Assert(BB == &BB->getParent()->front(), - "llvm.frameescape used outside of entry block", &CI); + "llvm.localescape used outside of entry block", CS); Assert(!SawFrameEscape, - "multiple calls to llvm.frameescape in one function", &CI); - for (Value *Arg : CI.arg_operands()) { + "multiple calls to llvm.localescape in one function", CS); + for (Value *Arg : CS.args()) { if (isa(Arg)) continue; // Null values are allowed as placeholders. auto *AI = dyn_cast(Arg->stripPointerCasts()); Assert(AI && AI->isStaticAlloca(), - "llvm.frameescape only accepts static allocas", &CI); + "llvm.localescape only accepts static allocas", CS); } - FrameEscapeInfo[BB->getParent()].first = CI.getNumArgOperands(); + FrameEscapeInfo[BB->getParent()].first = CS.getNumArgOperands(); SawFrameEscape = true; break; } - case Intrinsic::framerecover: { - Value *FnArg = CI.getArgOperand(0)->stripPointerCasts(); + case Intrinsic::localrecover: { + Value *FnArg = CS.getArgOperand(0)->stripPointerCasts(); Function *Fn = dyn_cast(FnArg); Assert(Fn && !Fn->isDeclaration(), - "llvm.framerecover first " + "llvm.localrecover first " "argument must be function defined in this module", - &CI); - auto *IdxArg = dyn_cast(CI.getArgOperand(2)); - Assert(IdxArg, "idx argument of llvm.framerecover must be a constant int", - &CI); + CS); + auto *IdxArg = dyn_cast(CS.getArgOperand(2)); + Assert(IdxArg, "idx argument of llvm.localrecover must be a constant int", + CS); auto &Entry = FrameEscapeInfo[Fn]; Entry.second = unsigned( std::max(uint64_t(Entry.second), IdxArg->getLimitedValue(~0U) + 1)); @@ -3234,123 +3613,143 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { } case Intrinsic::experimental_gc_statepoint: - Assert(!CI.isInlineAsm(), - "gc.statepoint support for inline assembly unimplemented", &CI); - Assert(CI.getParent()->getParent()->hasGC(), - "Enclosing function does not use GC.", &CI); + Assert(!CS.isInlineAsm(), + "gc.statepoint support for inline assembly unimplemented", CS); + Assert(CS.getParent()->getParent()->hasGC(), + "Enclosing function does not use GC.", CS); - VerifyStatepoint(ImmutableCallSite(&CI)); + VerifyStatepoint(CS); break; case Intrinsic::experimental_gc_result_int: case Intrinsic::experimental_gc_result_float: case Intrinsic::experimental_gc_result_ptr: case Intrinsic::experimental_gc_result: { - Assert(CI.getParent()->getParent()->hasGC(), - "Enclosing function does not use GC.", &CI); + Assert(CS.getParent()->getParent()->hasGC(), + "Enclosing function does not use GC.", CS); // Are we tied to a statepoint properly? - CallSite StatepointCS(CI.getArgOperand(0)); + CallSite StatepointCS(CS.getArgOperand(0)); const Function *StatepointFn = StatepointCS.getInstruction() ? StatepointCS.getCalledFunction() : nullptr; Assert(StatepointFn && StatepointFn->isDeclaration() && StatepointFn->getIntrinsicID() == Intrinsic::experimental_gc_statepoint, - "gc.result operand #1 must be from a statepoint", &CI, - CI.getArgOperand(0)); + "gc.result operand #1 must be from a statepoint", CS, + CS.getArgOperand(0)); // Assert that result type matches wrapped callee. - const Value *Target = StatepointCS.getArgument(0); - const PointerType *PT = cast(Target->getType()); - const FunctionType *TargetFuncType = - cast(PT->getElementType()); - Assert(CI.getType() == TargetFuncType->getReturnType(), - "gc.result result type does not match wrapped callee", &CI); + const Value *Target = StatepointCS.getArgument(2); + 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; } case Intrinsic::experimental_gc_relocate: { - Assert(CI.getNumArgOperands() == 3, "wrong number of arguments", &CI); + Assert(CS.getNumArgOperands() == 3, "wrong number of arguments", CS); // Check that this relocate is correctly tied to the statepoint // This is case for relocate on the unwinding path of an invoke statepoint if (ExtractValueInst *ExtractValue = - dyn_cast(CI.getArgOperand(0))) { + dyn_cast(CS.getArgOperand(0))) { Assert(isa(ExtractValue->getAggregateOperand()), "gc relocate on unwind path incorrectly linked to the statepoint", - &CI); + CS); - const BasicBlock *invokeBB = + const BasicBlock *InvokeBB = ExtractValue->getParent()->getUniquePredecessor(); // Landingpad relocates should have only one predecessor with invoke // statepoint terminator - Assert(invokeBB, "safepoints should have unique landingpads", + Assert(InvokeBB, "safepoints should have unique landingpads", ExtractValue->getParent()); - Assert(invokeBB->getTerminator(), "safepoint block should be well formed", - invokeBB); - Assert(isStatepoint(invokeBB->getTerminator()), - "gc relocate should be linked to a statepoint", invokeBB); + Assert(InvokeBB->getTerminator(), "safepoint block should be well formed", + InvokeBB); + Assert(isStatepoint(InvokeBB->getTerminator()), + "gc relocate should be linked to a statepoint", InvokeBB); } else { // In all other cases relocate should be tied to the statepoint directly. // This covers relocates on a normal return path of invoke statepoint and // relocates of a call statepoint - auto Token = CI.getArgOperand(0); + auto Token = CS.getArgOperand(0); Assert(isa(Token) && isStatepoint(cast(Token)), - "gc relocate is incorrectly tied to the statepoint", &CI, Token); + "gc relocate is incorrectly tied to the statepoint", CS, Token); } // Verify rest of the relocate arguments - GCRelocateOperands ops(&CI); - ImmutableCallSite StatepointCS(ops.statepoint()); + GCRelocateOperands Ops(CS); + ImmutableCallSite StatepointCS(Ops.getStatepoint()); // Both the base and derived must be piped through the safepoint - Value* Base = CI.getArgOperand(1); + Value* Base = CS.getArgOperand(1); Assert(isa(Base), - "gc.relocate operand #2 must be integer offset", &CI); + "gc.relocate operand #2 must be integer offset", CS); - Value* Derived = CI.getArgOperand(2); + Value* Derived = CS.getArgOperand(2); Assert(isa(Derived), - "gc.relocate operand #3 must be integer offset", &CI); + "gc.relocate operand #3 must be integer offset", CS); const int BaseIndex = cast(Base)->getZExtValue(); const int DerivedIndex = cast(Derived)->getZExtValue(); // Check the bounds Assert(0 <= BaseIndex && BaseIndex < (int)StatepointCS.arg_size(), - "gc.relocate: statepoint base index out of bounds", &CI); + "gc.relocate: statepoint base index out of bounds", CS); Assert(0 <= DerivedIndex && DerivedIndex < (int)StatepointCS.arg_size(), - "gc.relocate: statepoint derived index out of bounds", &CI); + "gc.relocate: statepoint derived index out of bounds", CS); // Check that BaseIndex and DerivedIndex fall within the 'gc parameters' // section of the statepoint's argument Assert(StatepointCS.arg_size() > 0, "gc.statepoint: insufficient arguments"); - Assert(isa(StatepointCS.getArgument(1)), + Assert(isa(StatepointCS.getArgument(3)), "gc.statement: number of call arguments must be constant integer"); const unsigned NumCallArgs = - cast(StatepointCS.getArgument(1))->getZExtValue(); - Assert(StatepointCS.arg_size() > NumCallArgs+3, + cast(StatepointCS.getArgument(3))->getZExtValue(); + Assert(StatepointCS.arg_size() > NumCallArgs + 5, "gc.statepoint: mismatch in number of call arguments"); - Assert(isa(StatepointCS.getArgument(NumCallArgs+3)), + Assert(isa(StatepointCS.getArgument(NumCallArgs + 5)), + "gc.statepoint: number of transition arguments must be " + "a constant integer"); + const int NumTransitionArgs = + cast(StatepointCS.getArgument(NumCallArgs + 5)) + ->getZExtValue(); + const int DeoptArgsStart = 4 + NumCallArgs + 1 + NumTransitionArgs + 1; + Assert(isa(StatepointCS.getArgument(DeoptArgsStart)), "gc.statepoint: number of deoptimization arguments must be " "a constant integer"); const int NumDeoptArgs = - cast(StatepointCS.getArgument(NumCallArgs + 3))->getZExtValue(); - const int GCParamArgsStart = NumCallArgs + NumDeoptArgs + 4; + cast(StatepointCS.getArgument(DeoptArgsStart))->getZExtValue(); + const int GCParamArgsStart = DeoptArgsStart + 1 + NumDeoptArgs; const int GCParamArgsEnd = StatepointCS.arg_size(); Assert(GCParamArgsStart <= BaseIndex && BaseIndex < GCParamArgsEnd, "gc.relocate: statepoint base index doesn't fall within the " "'gc parameters' section of the statepoint call", - &CI); + CS); Assert(GCParamArgsStart <= DerivedIndex && DerivedIndex < GCParamArgsEnd, "gc.relocate: statepoint derived index doesn't fall within the " "'gc parameters' section of the statepoint call", - &CI); - - // Assert that the result type matches the type of the relocated pointer - GCRelocateOperands Operands(&CI); - Assert(Operands.derivedPtr()->getType() == CI.getType(), - "gc.relocate: relocating a pointer shouldn't change its type", &CI); + CS); + + // Relocated value must be a pointer type, but gc_relocate does not need to return the + // same pointer type as the relocated pointer. It can be casted to the correct type later + // if it's desired. However, they must have the same address space. + GCRelocateOperands Operands(CS); + Assert(Operands.getDerivedPtr()->getType()->isPointerTy(), + "gc.relocate: relocated value must be a gc pointer", CS); + + // gc_relocate return type must be a pointer type, and is verified earlier in + // VerifyIntrinsicType(). + Assert(cast(CS.getType())->getAddressSpace() == + cast(Operands.getDerivedPtr()->getType())->getAddressSpace(), + "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; } }; @@ -3360,18 +3759,18 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) { /// /// This carefully grabs the subprogram from a local scope, avoiding the /// built-in assertions that would typically fire. -static MDSubprogram *getSubprogram(Metadata *LocalScope) { +static DISubprogram *getSubprogram(Metadata *LocalScope) { if (!LocalScope) return nullptr; - if (auto *SP = dyn_cast(LocalScope)) + if (auto *SP = dyn_cast(LocalScope)) return SP; - if (auto *LB = dyn_cast(LocalScope)) + if (auto *LB = dyn_cast(LocalScope)) return getSubprogram(LB->getRawScope()); // Just return null; broken scope chains are checked elsewhere. - assert(!isa(LocalScope) && "Unknown type of local scope"); + assert(!isa(LocalScope) && "Unknown type of local scope"); return nullptr; } @@ -3381,29 +3780,29 @@ void Verifier::visitDbgIntrinsic(StringRef Kind, DbgIntrinsicTy &DII) { Assert(isa(MD) || (isa(MD) && !cast(MD)->getNumOperands()), "invalid llvm.dbg." + Kind + " intrinsic address/value", &DII, MD); - Assert(isa(DII.getRawVariable()), + Assert(isa(DII.getRawVariable()), "invalid llvm.dbg." + Kind + " intrinsic variable", &DII, DII.getRawVariable()); - Assert(isa(DII.getRawExpression()), + Assert(isa(DII.getRawExpression()), "invalid llvm.dbg." + Kind + " intrinsic expression", &DII, DII.getRawExpression()); // Ignore broken !dbg attachments; they're checked elsewhere. if (MDNode *N = DII.getDebugLoc().getAsMDNode()) - if (!isa(N)) + if (!isa(N)) return; BasicBlock *BB = DII.getParent(); Function *F = BB ? BB->getParent() : nullptr; // The scopes for variables and !dbg attachments must agree. - MDLocalVariable *Var = DII.getVariable(); - MDLocation *Loc = DII.getDebugLoc(); + DILocalVariable *Var = DII.getVariable(); + DILocation *Loc = DII.getDebugLoc(); Assert(Loc, "llvm.dbg." + Kind + " intrinsic requires a !dbg attachment", &DII, BB, F); - MDSubprogram *VarSP = getSubprogram(Var->getRawScope()); - MDSubprogram *LocSP = getSubprogram(Loc->getRawScope()); + DISubprogram *VarSP = getSubprogram(Var->getRawScope()); + DISubprogram *LocSP = getSubprogram(Loc->getRawScope()); if (!VarSP || !LocSP) return; // Broken scope chains are checked elsewhere. @@ -3414,16 +3813,16 @@ void Verifier::visitDbgIntrinsic(StringRef Kind, DbgIntrinsicTy &DII) { } template -static uint64_t getVariableSize(const MDLocalVariable &V, const MapTy &Map) { +static uint64_t getVariableSize(const DILocalVariable &V, const MapTy &Map) { // Be careful of broken types (checked elsewhere). const Metadata *RawType = V.getRawType(); while (RawType) { // Try to get the size directly. - if (auto *T = dyn_cast(RawType)) + if (auto *T = dyn_cast(RawType)) if (uint64_t Size = T->getSizeInBits()) return Size; - if (auto *DT = dyn_cast(RawType)) { + if (auto *DT = dyn_cast(RawType)) { // Look at the base type. RawType = DT->getRawBaseType(); continue; @@ -3446,15 +3845,15 @@ static uint64_t getVariableSize(const MDLocalVariable &V, const MapTy &Map) { template void Verifier::verifyBitPieceExpression(const DbgInfoIntrinsic &I, const MapTy &TypeRefs) { - MDLocalVariable *V; - MDExpression *E; + DILocalVariable *V; + DIExpression *E; if (auto *DVI = dyn_cast(&I)) { - V = dyn_cast_or_null(DVI->getRawVariable()); - E = dyn_cast_or_null(DVI->getRawExpression()); + V = dyn_cast_or_null(DVI->getRawVariable()); + E = dyn_cast_or_null(DVI->getRawExpression()); } else { auto *DDI = cast(&I); - V = dyn_cast_or_null(DDI->getRawVariable()); - E = dyn_cast_or_null(DDI->getRawExpression()); + V = dyn_cast_or_null(DDI->getRawVariable()); + E = dyn_cast_or_null(DDI->getRawExpression()); } // We don't know whether this intrinsic verified correctly. @@ -3465,6 +3864,15 @@ void Verifier::verifyBitPieceExpression(const DbgInfoIntrinsic &I, if (!E->isBitPiece()) return; + // The frontend helps out GDB by emitting the members of local anonymous + // unions as artificial local variables with shared storage. When SROA splits + // the storage for artificial local variables that are smaller than the entire + // union, the overhang piece will be outside of the allotted space for the + // variable and this check fails. + // FIXME: Remove this check as soon as clang stops doing this; it hides bugs. + if (V->isArtificial()) + return; + // If there's no size, the type is broken, but that should be checked // elsewhere. uint64_t VarSize = getVariableSize(*V, TypeRefs); @@ -3490,11 +3898,11 @@ void Verifier::verifyTypeRefs() { return; // Visit all the compile units again to map the type references. - SmallDenseMap TypeRefs; + SmallDenseMap TypeRefs; for (auto *CU : CUs->operands()) - if (auto Ts = cast(CU)->getRetainedTypes()) - for (MDType *Op : Ts) - if (auto *T = dyn_cast(Op)) + if (auto Ts = cast(CU)->getRetainedTypes()) + for (DIType *Op : Ts) + if (auto *T = dyn_cast_or_null(Op)) if (auto *S = T->getRawIdentifier()) { UnresolvedTypeRefs.erase(S); TypeRefs.insert(std::make_pair(S, T));