[Attributes] Assert correct attribute constructor is used (NFCI)
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 12 Jul 2021 18:54:58 +0000 (20:54 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 12 Jul 2021 19:11:59 +0000 (21:11 +0200)
Assert that enum/int/type attributes go through the constructor
they are supposed to use.

To make sure this can't happen via invalid bitcode, explicitly
verify that the attribute kind if correct there.

llvm/include/llvm/IR/Attributes.h
llvm/lib/Bitcode/Reader/BitcodeReader.cpp
llvm/lib/IR/Attributes.cpp

index 4c2a366..2f04c02 100644 (file)
@@ -80,6 +80,12 @@ public:
 
   static const unsigned NumTypeAttrKinds = LastTypeAttr - FirstTypeAttr + 1;
 
+  static bool isEnumAttrKind(AttrKind Kind) {
+    return Kind >= FirstEnumAttr && Kind <= LastEnumAttr;
+  }
+  static bool isIntAttrKind(AttrKind Kind) {
+    return Kind >= FirstIntAttr && Kind <= LastIntAttr;
+  }
   static bool isTypeAttrKind(AttrKind Kind) {
     return Kind >= FirstTypeAttr && Kind <= LastTypeAttr;
   }
index 585527f..c9c1cef 100644 (file)
@@ -1599,12 +1599,16 @@ Error BitcodeReader::parseAttributeGroupBlock() {
             B.addStructRetAttr(nullptr);
           else if (Kind == Attribute::InAlloca)
             B.addInAllocaAttr(nullptr);
-
-          B.addAttribute(Kind);
+          else if (Attribute::isEnumAttrKind(Kind))
+            B.addAttribute(Kind);
+          else
+            return error("Not an enum attribute");
         } else if (Record[i] == 1) { // Integer attribute
           Attribute::AttrKind Kind;
           if (Error Err = parseAttrKind(Record[++i], &Kind))
             return Err;
+          if (!Attribute::isIntAttrKind(Kind))
+            return error("Not an int attribute");
           if (Kind == Attribute::Alignment)
             B.addAlignmentAttr(Record[++i]);
           else if (Kind == Attribute::StackAlignment)
index 45f7f18..3c3ffea 100644 (file)
@@ -91,6 +91,11 @@ static std::pair<unsigned, unsigned> unpackVScaleRangeArgs(uint64_t Value) {
 
 Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
                          uint64_t Val) {
+  if (Val)
+    assert(Attribute::isIntAttrKind(Kind) && "Not an int attribute");
+  else
+    assert(Attribute::isEnumAttrKind(Kind) && "Not an enum attribute");
+
   LLVMContextImpl *pImpl = Context.pImpl;
   FoldingSetNodeID ID;
   ID.AddInteger(Kind);