[llvm] 98204a2 - [Bitcode] Verify types for aggregate initializers

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 28 02:21:49 PST 2024


Author: Nikita Popov
Date: 2024-11-28T11:21:38+01:00
New Revision: 98204a2e5bb754b0260175e42614c5463807beb5

URL: https://github.com/llvm/llvm-project/commit/98204a2e5bb754b0260175e42614c5463807beb5
DIFF: https://github.com/llvm/llvm-project/commit/98204a2e5bb754b0260175e42614c5463807beb5.diff

LOG: [Bitcode] Verify types for aggregate initializers

Unfortunately all the nice error messages get lost because we
don't forward errors from lazy value materialization.

Fixes https://github.com/llvm/llvm-project/issues/117707.

Added: 
    llvm/test/Bitcode/Inputs/invalid-initializer.bc

Modified: 
    llvm/lib/Bitcode/Reader/BitcodeReader.cpp
    llvm/test/Bitcode/invalid.test

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 11fbe6e6158eec..a585a24a022467 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -1663,15 +1663,42 @@ Expected<Value *> BitcodeReader::materializeValue(unsigned StartValID,
           C = BlockAddress::get(Fn, BB);
           break;
         }
-        case BitcodeConstant::ConstantStructOpcode:
-          C = ConstantStruct::get(cast<StructType>(BC->getType()), ConstOps);
+        case BitcodeConstant::ConstantStructOpcode: {
+          auto *ST = cast<StructType>(BC->getType());
+          if (ST->getNumElements() != ConstOps.size())
+            return error("Invalid number of elements in struct initializer");
+
+          for (const auto [Ty, Op] : zip(ST->elements(), ConstOps))
+            if (Op->getType() != Ty)
+              return error("Incorrect type in struct initializer");
+
+          C = ConstantStruct::get(ST, ConstOps);
           break;
-        case BitcodeConstant::ConstantArrayOpcode:
-          C = ConstantArray::get(cast<ArrayType>(BC->getType()), ConstOps);
+        }
+        case BitcodeConstant::ConstantArrayOpcode: {
+          auto *AT = cast<ArrayType>(BC->getType());
+          if (AT->getNumElements() != ConstOps.size())
+            return error("Invalid number of elements in array initializer");
+
+          for (Constant *Op : ConstOps)
+            if (Op->getType() != AT->getElementType())
+              return error("Incorrect type in array initializer");
+
+          C = ConstantArray::get(AT, ConstOps);
           break;
-        case BitcodeConstant::ConstantVectorOpcode:
+        }
+        case BitcodeConstant::ConstantVectorOpcode: {
+          auto *VT = cast<FixedVectorType>(BC->getType());
+          if (VT->getNumElements() != ConstOps.size())
+            return error("Invalid number of elements in vector initializer");
+
+          for (Constant *Op : ConstOps)
+            if (Op->getType() != VT->getElementType())
+              return error("Incorrect type in vector initializer");
+
           C = ConstantVector::get(ConstOps);
           break;
+        }
         case Instruction::GetElementPtr:
           C = ConstantExpr::getGetElementPtr(
               BC->SrcElemTy, ConstOps[0], ArrayRef(ConstOps).drop_front(),

diff  --git a/llvm/test/Bitcode/Inputs/invalid-initializer.bc b/llvm/test/Bitcode/Inputs/invalid-initializer.bc
new file mode 100644
index 00000000000000..df5b6d37bde5e6
Binary files /dev/null and b/llvm/test/Bitcode/Inputs/invalid-initializer.bc 
diff er

diff  --git a/llvm/test/Bitcode/invalid.test b/llvm/test/Bitcode/invalid.test
index 5543005ad54c9f..66286671a866b3 100644
--- a/llvm/test/Bitcode/invalid.test
+++ b/llvm/test/Bitcode/invalid.test
@@ -285,3 +285,8 @@ RUN: not llvm-dis -disable-output %p/Inputs/invalid-forward-declare.bc 2>&1 | \
 RUN:   FileCheck --check-prefix=INVALID-FORWARD-DECLARE %s
 
 INVALID-FORWARD-DECLARE: Assigned value does not match type of forward declaration
+
+RUN: not llvm-dis -disable-output %p/Inputs/invalid-initializer.bc 2>&1 | \
+RUN:   FileCheck --check-prefix=INVALID-INITIALIZER %s
+
+INVALID-INITIALIZER: Invalid record


        


More information about the llvm-commits mailing list