From 98204a2e5bb754b0260175e42614c5463807beb5 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 28 Nov 2024 11:15:32 +0100 Subject: [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. --- llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 37 ++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp') diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 11fbe6e..a585a24 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1663,15 +1663,42 @@ Expected BitcodeReader::materializeValue(unsigned StartValID, C = BlockAddress::get(Fn, BB); break; } - case BitcodeConstant::ConstantStructOpcode: - C = ConstantStruct::get(cast(BC->getType()), ConstOps); + case BitcodeConstant::ConstantStructOpcode: { + auto *ST = cast(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(BC->getType()), ConstOps); + } + case BitcodeConstant::ConstantArrayOpcode: { + auto *AT = cast(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(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(), -- cgit v1.1