diff --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h index 3ef8a3bbfd7972..3871db9a200ed6 100644 --- a/llvm/include/llvm/IR/Attributes.h +++ b/llvm/include/llvm/IR/Attributes.h @@ -111,6 +111,9 @@ class Attribute { 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 index da6e993e2e586e..8741c0ca9b3d6b 100644 --- a/llvm/lib/IR/AttributeImpl.h +++ b/llvm/lib/IR/AttributeImpl.h @@ -134,10 +134,7 @@ class IntAttributeImpl : public EnumAttributeImpl { 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 index 78ee00d7821f77..5f0008e38fdaba 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -199,6 +199,14 @@ StringRef Attribute::getNameFromAttrKind(Attribute::AttrKind AttrKind) { } } +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 @@ void AttrBuilder::clear() { 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 index 6698a6860b3942..6062baa70deee4 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -1572,6 +1572,13 @@ void Verifier::verifyAttributeTypes(AttributeSet Attrs, bool IsFunction, 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 index eea947fdb0d931..266d1026856072 100644 --- a/llvm/lib/Transforms/Utils/KnowledgeRetention.cpp +++ b/llvm/lib/Transforms/Utils/KnowledgeRetention.cpp @@ -124,6 +124,11 @@ struct AssumeBuilderState { 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)