diff --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h --- a/llvm/include/llvm/IR/Attributes.h +++ b/llvm/include/llvm/IR/Attributes.h @@ -111,6 +111,9 @@ static StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind); + /// Return true if and only if the attribute has an Argument. + static bool doesAttrKindHaveArgument(Attribute::AttrKind AttrKind); + //===--------------------------------------------------------------------===// // Attribute Accessors //===--------------------------------------------------------------------===// diff --git a/llvm/lib/IR/AttributeImpl.h b/llvm/lib/IR/AttributeImpl.h --- a/llvm/lib/IR/AttributeImpl.h +++ b/llvm/lib/IR/AttributeImpl.h @@ -134,10 +134,7 @@ public: IntAttributeImpl(Attribute::AttrKind Kind, uint64_t Val) : EnumAttributeImpl(IntAttrEntry, Kind), Val(Val) { - assert((Kind == Attribute::Alignment || Kind == Attribute::StackAlignment || - Kind == Attribute::Dereferenceable || - Kind == Attribute::DereferenceableOrNull || - Kind == Attribute::AllocSize) && + assert(Attribute::doesAttrKindHaveArgument(Kind) && "Wrong kind for int attribute!"); } diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -199,6 +199,14 @@ } } +bool Attribute::doesAttrKindHaveArgument(Attribute::AttrKind AttrKind) { + return AttrKind == Attribute::Alignment || + AttrKind == Attribute::StackAlignment || + AttrKind == Attribute::Dereferenceable || + AttrKind == Attribute::AllocSize || + AttrKind == Attribute::DereferenceableOrNull; +} + //===----------------------------------------------------------------------===// // Attribute Accessor Methods //===----------------------------------------------------------------------===// @@ -1472,8 +1480,7 @@ AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) { assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!"); - assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment && - Val != Attribute::Dereferenceable && Val != Attribute::AllocSize && + assert(!Attribute::doesAttrKindHaveArgument(Val) && "Adding integer attribute without adding a value!"); Attrs[Val] = true; return *this; diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -1572,6 +1572,13 @@ if (A.isStringAttribute()) continue; + if (A.isIntAttribute() != + Attribute::doesAttrKindHaveArgument(A.getKindAsEnum())) { + CheckFailed("Attribute '" + A.getAsString() + "' should have an Argument", + V); + return; + } + if (isFuncOnlyAttr(A.getKindAsEnum())) { if (!IsFunction) { CheckFailed("Attribute '" + A.getAsString() + diff --git a/llvm/lib/Transforms/Utils/KnowledgeRetention.cpp b/llvm/lib/Transforms/Utils/KnowledgeRetention.cpp --- a/llvm/lib/Transforms/Utils/KnowledgeRetention.cpp +++ b/llvm/lib/Transforms/Utils/KnowledgeRetention.cpp @@ -124,6 +124,11 @@ SmallVector OpBundle; for (const AssumedKnowledge &Elem : AssumedKnowledgeSet) { SmallVector Args; + assert(Attribute::getAttrKindFromName(Elem.Name) == + Attribute::AttrKind::None || + static_cast(Elem.Argument) == + Attribute::doesAttrKindHaveArgument( + Attribute::getAttrKindFromName(Elem.Name))); if (Elem.WasOn.getPointer()) Args.push_back(Elem.WasOn.getPointer()); if (Elem.Argument)