diff options
Diffstat (limited to 'llvm/lib/Bitcode')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 556 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitstreamReader.cpp | 273 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 189 |
3 files changed, 705 insertions, 313 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index c33fc568abe..3e4ad52dc1e 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -105,18 +105,25 @@ static Error error(const Twine &Message) { Message, make_error_code(BitcodeError::CorruptedBitcode)); } -/// Helper to read the header common to all bitcode files. -static bool hasValidBitcodeHeader(BitstreamCursor &Stream) { - // Sniff for the signature. - if (!Stream.canSkipToPos(4) || - Stream.Read(8) != 'B' || - Stream.Read(8) != 'C' || - Stream.Read(4) != 0x0 || - Stream.Read(4) != 0xC || - Stream.Read(4) != 0xE || - Stream.Read(4) != 0xD) - return false; - return true; +static Error hasInvalidBitcodeHeader(BitstreamCursor &Stream) { + if (!Stream.canSkipToPos(4)) + return createStringError(std::errc::illegal_byte_sequence, + "file too small to contain bitcode header"); + for (unsigned C : {'B', 'C'}) + if (Expected<SimpleBitstreamCursor::word_t> Res = Stream.Read(8)) { + if (Res.get() != C) + return createStringError(std::errc::illegal_byte_sequence, + "file doesn't start with bitcode header"); + } else + return Res.takeError(); + for (unsigned C : {0x0, 0xC, 0xE, 0xD}) + if (Expected<SimpleBitstreamCursor::word_t> Res = Stream.Read(4)) { + if (Res.get() != C) + return createStringError(std::errc::illegal_byte_sequence, + "file doesn't start with bitcode header"); + } else + return Res.takeError(); + return Error::success(); } static Expected<BitstreamCursor> initStream(MemoryBufferRef Buffer) { @@ -133,8 +140,8 @@ static Expected<BitstreamCursor> initStream(MemoryBufferRef Buffer) { return error("Invalid bitcode wrapper header"); BitstreamCursor Stream(ArrayRef<uint8_t>(BufPtr, BufEnd)); - if (!hasValidBitcodeHeader(Stream)) - return error("Invalid bitcode signature"); + if (Error Err = hasInvalidBitcodeHeader(Stream)) + return std::move(Err); return std::move(Stream); } @@ -164,8 +171,8 @@ static void stripTBAA(Module *M) { /// Read the "IDENTIFICATION_BLOCK_ID" block, do some basic enforcement on the /// "epoch" encoded in the bitcode, and return the producer name if any. static Expected<std::string> readIdentificationBlock(BitstreamCursor &Stream) { - if (Stream.EnterSubBlock(bitc::IDENTIFICATION_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::IDENTIFICATION_BLOCK_ID)) + return std::move(Err); // Read all the records. SmallVector<uint64_t, 64> Record; @@ -173,7 +180,11 @@ static Expected<std::string> readIdentificationBlock(BitstreamCursor &Stream) { std::string ProducerIdentification; while (true) { - BitstreamEntry Entry = Stream.advance(); + BitstreamEntry Entry; + if (Expected<BitstreamEntry> Res = Stream.advance()) + Entry = Res.get(); + else + return Res.takeError(); switch (Entry.Kind) { default: @@ -188,8 +199,10 @@ static Expected<std::string> readIdentificationBlock(BitstreamCursor &Stream) { // Read a record. Record.clear(); - unsigned BitCode = Stream.readRecord(Entry.ID, Record); - switch (BitCode) { + Expected<unsigned> MaybeBitCode = Stream.readRecord(Entry.ID, Record); + if (!MaybeBitCode) + return MaybeBitCode.takeError(); + switch (unsigned BitCode = MaybeBitCode.get()) { default: // Default behavior: reject return error("Invalid value"); case bitc::IDENTIFICATION_CODE_STRING: // IDENTIFICATION: [strchr x N] @@ -214,7 +227,12 @@ static Expected<std::string> readIdentificationCode(BitstreamCursor &Stream) { if (Stream.AtEndOfStream()) return ""; - BitstreamEntry Entry = Stream.advance(); + BitstreamEntry Entry; + if (Expected<BitstreamEntry> Res = Stream.advance()) + Entry = std::move(Res.get()); + else + return Res.takeError(); + switch (Entry.Kind) { case BitstreamEntry::EndBlock: case BitstreamEntry::Error: @@ -225,25 +243,30 @@ static Expected<std::string> readIdentificationCode(BitstreamCursor &Stream) { return readIdentificationBlock(Stream); // Ignore other sub-blocks. - if (Stream.SkipBlock()) - return error("Malformed block"); + if (Error Err = Stream.SkipBlock()) + return std::move(Err); continue; case BitstreamEntry::Record: - Stream.skipRecord(Entry.ID); - continue; + if (Expected<unsigned> Skipped = Stream.skipRecord(Entry.ID)) + continue; + else + return Skipped.takeError(); } } } static Expected<bool> hasObjCCategoryInModule(BitstreamCursor &Stream) { - if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) + return std::move(Err); SmallVector<uint64_t, 64> Record; // Read all the records for this module. while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -257,7 +280,10 @@ static Expected<bool> hasObjCCategoryInModule(BitstreamCursor &Stream) { } // Read a record. - switch (Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + switch (MaybeRecord.get()) { default: break; // Default behavior, ignore unknown content. case bitc::MODULE_CODE_SECTIONNAME: { // SECTIONNAME: [strchr x N] @@ -280,7 +306,11 @@ static Expected<bool> hasObjCCategory(BitstreamCursor &Stream) { // We expect a number of well-defined blocks, though we don't necessarily // need to understand them all. while (true) { - BitstreamEntry Entry = Stream.advance(); + BitstreamEntry Entry; + if (Expected<BitstreamEntry> Res = Stream.advance()) + Entry = std::move(Res.get()); + else + return Res.takeError(); switch (Entry.Kind) { case BitstreamEntry::Error: @@ -293,20 +323,22 @@ static Expected<bool> hasObjCCategory(BitstreamCursor &Stream) { return hasObjCCategoryInModule(Stream); // Ignore other sub-blocks. - if (Stream.SkipBlock()) - return error("Malformed block"); + if (Error Err = Stream.SkipBlock()) + return std::move(Err); continue; case BitstreamEntry::Record: - Stream.skipRecord(Entry.ID); - continue; + if (Expected<unsigned> Skipped = Stream.skipRecord(Entry.ID)) + continue; + else + return Skipped.takeError(); } } } static Expected<std::string> readModuleTriple(BitstreamCursor &Stream) { - if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) + return std::move(Err); SmallVector<uint64_t, 64> Record; @@ -314,7 +346,10 @@ static Expected<std::string> readModuleTriple(BitstreamCursor &Stream) { // Read all the records for this module. while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -328,7 +363,10 @@ static Expected<std::string> readModuleTriple(BitstreamCursor &Stream) { } // Read a record. - switch (Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + switch (MaybeRecord.get()) { default: break; // Default behavior, ignore unknown content. case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N] std::string S; @@ -347,7 +385,10 @@ static Expected<std::string> readTriple(BitstreamCursor &Stream) { // We expect a number of well-defined blocks, though we don't necessarily // need to understand them all. while (true) { - BitstreamEntry Entry = Stream.advance(); + Expected<BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::Error: @@ -360,13 +401,15 @@ static Expected<std::string> readTriple(BitstreamCursor &Stream) { return readModuleTriple(Stream); // Ignore other sub-blocks. - if (Stream.SkipBlock()) - return error("Malformed block"); + if (Error Err = Stream.SkipBlock()) + return std::move(Err); continue; case BitstreamEntry::Record: - Stream.skipRecord(Entry.ID); - continue; + if (llvm::Expected<unsigned> Skipped = Stream.skipRecord(Entry.ID)) + continue; + else + return Skipped.takeError(); } } } @@ -1253,8 +1296,8 @@ static void decodeLLVMAttributesForBitcode(AttrBuilder &B, } Error BitcodeReader::parseAttributeBlock() { - if (Stream.EnterSubBlock(bitc::PARAMATTR_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::PARAMATTR_BLOCK_ID)) + return Err; if (!MAttributes.empty()) return error("Invalid multiple blocks"); @@ -1265,7 +1308,10 @@ Error BitcodeReader::parseAttributeBlock() { // Read all the records. while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -1280,7 +1326,10 @@ Error BitcodeReader::parseAttributeBlock() { // Read a record. Record.clear(); - switch (Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + switch (MaybeRecord.get()) { default: // Default behavior: ignore. break; case bitc::PARAMATTR_CODE_ENTRY_OLD: // ENTRY: [paramidx0, attr0, ...] @@ -1454,8 +1503,8 @@ Error BitcodeReader::parseAttrKind(uint64_t Code, Attribute::AttrKind *Kind) { } Error BitcodeReader::parseAttributeGroupBlock() { - if (Stream.EnterSubBlock(bitc::PARAMATTR_GROUP_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::PARAMATTR_GROUP_BLOCK_ID)) + return Err; if (!MAttributeGroups.empty()) return error("Invalid multiple blocks"); @@ -1464,7 +1513,10 @@ Error BitcodeReader::parseAttributeGroupBlock() { // Read all the records. while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -1479,7 +1531,10 @@ Error BitcodeReader::parseAttributeGroupBlock() { // Read a record. Record.clear(); - switch (Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + switch (MaybeRecord.get()) { default: // Default behavior: ignore. break; case bitc::PARAMATTR_GRP_CODE_ENTRY: { // ENTRY: [grpid, idx, a0, a1, ...] @@ -1555,8 +1610,8 @@ Error BitcodeReader::parseAttributeGroupBlock() { } Error BitcodeReader::parseTypeTable() { - if (Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID_NEW)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID_NEW)) + return Err; return parseTypeTableBody(); } @@ -1572,7 +1627,10 @@ Error BitcodeReader::parseTypeTableBody() { // Read all the records for this type table. while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -1590,7 +1648,10 @@ Error BitcodeReader::parseTypeTableBody() { // Read a record. Record.clear(); Type *ResultTy = nullptr; - switch (Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + switch (MaybeRecord.get()) { default: return error("Invalid value"); case bitc::TYPE_CODE_NUMENTRY: // TYPE_CODE_NUMENTRY: [numentries] @@ -1800,8 +1861,8 @@ Error BitcodeReader::parseTypeTableBody() { } Error BitcodeReader::parseOperandBundleTags() { - if (Stream.EnterSubBlock(bitc::OPERAND_BUNDLE_TAGS_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::OPERAND_BUNDLE_TAGS_BLOCK_ID)) + return Err; if (!BundleTags.empty()) return error("Invalid multiple blocks"); @@ -1809,7 +1870,10 @@ Error BitcodeReader::parseOperandBundleTags() { SmallVector<uint64_t, 64> Record; while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -1824,7 +1888,10 @@ Error BitcodeReader::parseOperandBundleTags() { // Tags are implicitly mapped to integers by their order. - if (Stream.readRecord(Entry.ID, Record) != bitc::OPERAND_BUNDLE_TAG) + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + if (MaybeRecord.get() != bitc::OPERAND_BUNDLE_TAG) return error("Invalid record"); // OPERAND_BUNDLE_TAG: [strchr x N] @@ -1836,15 +1903,19 @@ Error BitcodeReader::parseOperandBundleTags() { } Error BitcodeReader::parseSyncScopeNames() { - if (Stream.EnterSubBlock(bitc::SYNC_SCOPE_NAMES_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::SYNC_SCOPE_NAMES_BLOCK_ID)) + return Err; if (!SSIDs.empty()) return error("Invalid multiple synchronization scope names blocks"); SmallVector<uint64_t, 64> Record; while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); + switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. case BitstreamEntry::Error: @@ -1861,7 +1932,10 @@ Error BitcodeReader::parseSyncScopeNames() { // Synchronization scope names are implicitly mapped to synchronization // scope IDs by their order. - if (Stream.readRecord(Entry.ID, Record) != bitc::SYNC_SCOPE_NAME) + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + if (MaybeRecord.get() != bitc::SYNC_SCOPE_NAME) return error("Invalid record"); SmallString<16> SSN; @@ -1902,22 +1976,18 @@ Expected<Value *> BitcodeReader::recordValue(SmallVectorImpl<uint64_t> &Record, /// Helper to note and return the current location, and jump to the given /// offset. -static uint64_t jumpToValueSymbolTable(uint64_t Offset, - BitstreamCursor &Stream) { +static Expected<uint64_t> jumpToValueSymbolTable(uint64_t Offset, + BitstreamCursor &Stream) { // Save the current parsing location so we can jump back at the end // of the VST read. uint64_t CurrentBit = Stream.GetCurrentBitNo(); - Stream.JumpToBit(Offset * 32); -#ifndef NDEBUG - // Do some checking if we are in debug mode. - BitstreamEntry Entry = Stream.advance(); - assert(Entry.Kind == BitstreamEntry::SubBlock); - assert(Entry.ID == bitc::VALUE_SYMTAB_BLOCK_ID); -#else - // In NDEBUG mode ignore the output so we don't get an unused variable - // warning. - Stream.advance(); -#endif + if (Error JumpFailed = Stream.JumpToBit(Offset * 32)) + return std::move(JumpFailed); + Expected<BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + assert(MaybeEntry.get().Kind == BitstreamEntry::SubBlock); + assert(MaybeEntry.get().ID == bitc::VALUE_SYMTAB_BLOCK_ID); return CurrentBit; } @@ -1942,12 +2012,15 @@ Error BitcodeReader::parseGlobalValueSymbolTable() { unsigned FuncBitcodeOffsetDelta = Stream.getAbbrevIDWidth() + bitc::BlockIDWidth; - if (Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID)) + return Err; SmallVector<uint64_t, 64> Record; while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: @@ -1960,7 +2033,10 @@ Error BitcodeReader::parseGlobalValueSymbolTable() { } Record.clear(); - switch (Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + switch (MaybeRecord.get()) { case bitc::VST_CODE_FNENTRY: // [valueid, offset] setDeferredFunctionInfo(FuncBitcodeOffsetDelta, cast<Function>(ValueList[Record[0]]), Record); @@ -1977,12 +2053,16 @@ Error BitcodeReader::parseValueSymbolTable(uint64_t Offset) { // VST (where we want to jump to the VST offset) and the function-level // VST (where we don't). if (Offset > 0) { - CurrentBit = jumpToValueSymbolTable(Offset, Stream); + Expected<uint64_t> MaybeCurrentBit = jumpToValueSymbolTable(Offset, Stream); + if (!MaybeCurrentBit) + return MaybeCurrentBit.takeError(); + CurrentBit = MaybeCurrentBit.get(); // If this module uses a string table, read this as a module-level VST. if (UseStrtab) { if (Error Err = parseGlobalValueSymbolTable()) return Err; - Stream.JumpToBit(CurrentBit); + if (Error JumpFailed = Stream.JumpToBit(CurrentBit)) + return JumpFailed; return Error::success(); } // Otherwise, the VST will be in a similar format to a function-level VST, @@ -2003,8 +2083,8 @@ Error BitcodeReader::parseValueSymbolTable(uint64_t Offset) { unsigned FuncBitcodeOffsetDelta = Stream.getAbbrevIDWidth() + bitc::BlockIDWidth; - if (Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID)) + return Err; SmallVector<uint64_t, 64> Record; @@ -2014,7 +2094,10 @@ Error BitcodeReader::parseValueSymbolTable(uint64_t Offset) { SmallString<128> ValueName; while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -2022,7 +2105,8 @@ Error BitcodeReader::parseValueSymbolTable(uint64_t Offset) { return error("Malformed block"); case BitstreamEntry::EndBlock: if (Offset > 0) - Stream.JumpToBit(CurrentBit); + if (Error JumpFailed = Stream.JumpToBit(CurrentBit)) + return JumpFailed; return Error::success(); case BitstreamEntry::Record: // The interesting case. @@ -2031,7 +2115,10 @@ Error BitcodeReader::parseValueSymbolTable(uint64_t Offset) { // Read a record. Record.clear(); - switch (Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + switch (MaybeRecord.get()) { default: // Default behavior: unknown type. break; case bitc::VST_CODE_ENTRY: { // VST_CODE_ENTRY: [valueid, namechar x N] @@ -2176,8 +2263,8 @@ static APInt readWideAPInt(ArrayRef<uint64_t> Vals, unsigned TypeBits) { } Error BitcodeReader::parseConstants() { - if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID)) + return Err; SmallVector<uint64_t, 64> Record; @@ -2186,7 +2273,10 @@ Error BitcodeReader::parseConstants() { unsigned NextCstNo = ValueList.size(); while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -2209,8 +2299,10 @@ Error BitcodeReader::parseConstants() { Record.clear(); Type *VoidType = Type::getVoidTy(Context); Value *V = nullptr; - unsigned BitCode = Stream.readRecord(Entry.ID, Record); - switch (BitCode) { + Expected<unsigned> MaybeBitCode = Stream.readRecord(Entry.ID, Record); + if (!MaybeBitCode) + return MaybeBitCode.takeError(); + switch (unsigned BitCode = MaybeBitCode.get()) { default: // Default behavior: unknown constant case bitc::CST_CODE_UNDEF: // UNDEF V = UndefValue::get(CurTy); @@ -2669,14 +2761,17 @@ Error BitcodeReader::parseConstants() { } Error BitcodeReader::parseUseLists() { - if (Stream.EnterSubBlock(bitc::USELIST_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::USELIST_BLOCK_ID)) + return Err; // Read all the records. SmallVector<uint64_t, 64> Record; while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -2692,7 +2787,10 @@ Error BitcodeReader::parseUseLists() { // Read a use list record. Record.clear(); bool IsBB = false; - switch (Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + switch (MaybeRecord.get()) { default: // Default behavior: unknown type. break; case bitc::USELIST_CODE_BB: @@ -2741,15 +2839,16 @@ Error BitcodeReader::rememberAndSkipMetadata() { DeferredMetadataInfo.push_back(CurBit); // Skip over the block for now. - if (Stream.SkipBlock()) - return error("Invalid record"); + if (Error Err = Stream.SkipBlock()) + return Err; return Error::success(); } Error BitcodeReader::materializeMetadata() { for (uint64_t BitPos : DeferredMetadataInfo) { // Move the bit stream to the saved position. - Stream.JumpToBit(BitPos); + if (Error JumpFailed = Stream.JumpToBit(BitPos)) + return JumpFailed; if (Error Err = MDLoader->parseModuleMetadata()) return Err; } @@ -2787,8 +2886,8 @@ Error BitcodeReader::rememberAndSkipFunctionBody() { DeferredFunctionInfo[Fn] = CurBit; // Skip over the function block for now. - if (Stream.SkipBlock()) - return error("Invalid record"); + if (Error Err = Stream.SkipBlock()) + return Err; return Error::success(); } @@ -2835,7 +2934,8 @@ Error BitcodeReader::globalCleanup() { /// or if we have an anonymous function being materialized, since anonymous /// functions do not have a name and are therefore not in the VST. Error BitcodeReader::rememberAndSkipFunctionBodies() { - Stream.JumpToBit(NextUnreadBit); + if (Error JumpFailed = Stream.JumpToBit(NextUnreadBit)) + return JumpFailed; if (Stream.AtEndOfStream()) return error("Could not find function in stream"); @@ -2850,7 +2950,11 @@ Error BitcodeReader::rememberAndSkipFunctionBodies() { SmallVector<uint64_t, 64> Record; while (true) { - BitstreamEntry Entry = Stream.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + llvm::BitstreamEntry Entry = MaybeEntry.get(); + switch (Entry.Kind) { default: return error("Expect SubBlock"); @@ -2869,7 +2973,12 @@ Error BitcodeReader::rememberAndSkipFunctionBodies() { } bool BitcodeReaderBase::readBlockInfo() { - Optional<BitstreamBlockInfo> NewBlockInfo = Stream.ReadBlockInfoBlock(); + Expected<Optional<BitstreamBlockInfo>> MaybeNewBlockInfo = + Stream.ReadBlockInfoBlock(); + if (!MaybeNewBlockInfo) + return true; // FIXME Handle the error. + Optional<BitstreamBlockInfo> NewBlockInfo = + std::move(MaybeNewBlockInfo.get()); if (!NewBlockInfo) return true; BlockInfo = std::move(*NewBlockInfo); @@ -3205,16 +3314,20 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord( Error BitcodeReader::parseModule(uint64_t ResumeBit, bool ShouldLazyLoadMetadata) { - if (ResumeBit) - Stream.JumpToBit(ResumeBit); - else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) - return error("Invalid record"); + if (ResumeBit) { + if (Error JumpFailed = Stream.JumpToBit(ResumeBit)) + return JumpFailed; + } else if (Error Err = Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) + return Err; SmallVector<uint64_t, 64> Record; // Read all the records for this module. while (true) { - BitstreamEntry Entry = Stream.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + llvm::BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::Error: @@ -3225,8 +3338,8 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, case BitstreamEntry::SubBlock: switch (Entry.ID) { default: // Skip unknown content. - if (Stream.SkipBlock()) - return error("Invalid record"); + if (Error Err = Stream.SkipBlock()) + return Err; break; case bitc::BLOCKINFO_BLOCK_ID: if (readBlockInfo()) @@ -3259,8 +3372,8 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, // We must have had a VST forward declaration record, which caused // the parser to jump to and parse the VST earlier. assert(VSTOffset > 0); - if (Stream.SkipBlock()) - return error("Invalid record"); + if (Error Err = Stream.SkipBlock()) + return Err; } break; case bitc::CONSTANTS_BLOCK_ID: @@ -3312,8 +3425,8 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, // materializing functions. The ResumeBit points to the // start of the last function block recorded in the // DeferredFunctionInfo map. Skip it. - if (Stream.SkipBlock()) - return error("Invalid record"); + if (Error Err = Stream.SkipBlock()) + return Err; continue; } } @@ -3357,8 +3470,10 @@ Error BitcodeReader::parseModule(uint64_t ResumeBit, } // Read a record. - auto BitCode = Stream.readRecord(Entry.ID, Record); - switch (BitCode) { + Expected<unsigned> MaybeBitCode = Stream.readRecord(Entry.ID, Record); + if (!MaybeBitCode) + return MaybeBitCode.takeError(); + switch (unsigned BitCode = MaybeBitCode.get()) { default: break; // Default behavior, ignore unknown content. case bitc::MODULE_CODE_VERSION: { Expected<unsigned> VersionOrErr = parseVersionRecord(Record); @@ -3485,8 +3600,8 @@ void BitcodeReader::propagateByValTypes(CallBase *CB) { /// Lazily parse the specified function body block. Error BitcodeReader::parseFunctionBody(Function *F) { - if (Stream.EnterSubBlock(bitc::FUNCTION_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::FUNCTION_BLOCK_ID)) + return Err; // Unexpected unresolved metadata when parsing function. if (MDLoader->hasFwdRefs()) @@ -3520,7 +3635,10 @@ Error BitcodeReader::parseFunctionBody(Function *F) { SmallVector<uint64_t, 64> Record; while (true) { - BitstreamEntry Entry = Stream.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + llvm::BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::Error: @@ -3531,8 +3649,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) { case BitstreamEntry::SubBlock: switch (Entry.ID) { default: // Skip unknown content. - if (Stream.SkipBlock()) - return error("Invalid record"); + if (Error Err = Stream.SkipBlock()) + return Err; break; case bitc::CONSTANTS_BLOCK_ID: if (Error Err = parseConstants()) @@ -3568,8 +3686,10 @@ Error BitcodeReader::parseFunctionBody(Function *F) { // Read a record. Record.clear(); Instruction *I = nullptr; - unsigned BitCode = Stream.readRecord(Entry.ID, Record); - switch (BitCode) { + Expected<unsigned> MaybeBitCode = Stream.readRecord(Entry.ID, Record); + if (!MaybeBitCode) + return MaybeBitCode.takeError(); + switch (unsigned BitCode = MaybeBitCode.get()) { default: // Default behavior: reject return error("Invalid value"); case bitc::FUNC_CODE_DECLAREBLOCKS: { // DECLAREBLOCKS: [nblocks] @@ -4922,8 +5042,8 @@ Error BitcodeReader::materialize(GlobalValue *GV) { return Err; // Move the bit stream to the saved position of the deferred function body. - Stream.JumpToBit(DFII->second); - + if (Error JumpFailed = Stream.JumpToBit(DFII->second)) + return JumpFailed; if (Error Err = parseFunctionBody(F)) return Err; F->setIsMaterializable(false); @@ -5086,10 +5206,13 @@ Error ModuleSummaryIndexBitcodeReader::parseValueSymbolTable( return Error::success(); assert(Offset > 0 && "Expected non-zero VST offset"); - uint64_t CurrentBit = jumpToValueSymbolTable(Offset, Stream); + Expected<uint64_t> MaybeCurrentBit = jumpToValueSymbolTable(Offset, Stream); + if (!MaybeCurrentBit) + return MaybeCurrentBit.takeError(); + uint64_t CurrentBit = MaybeCurrentBit.get(); - if (Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID)) + return Err; SmallVector<uint64_t, 64> Record; @@ -5097,7 +5220,10 @@ Error ModuleSummaryIndexBitcodeReader::parseValueSymbolTable( SmallString<128> ValueName; while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -5105,7 +5231,8 @@ Error ModuleSummaryIndexBitcodeReader::parseValueSymbolTable( return error("Malformed block"); case BitstreamEntry::EndBlock: // Done parsing VST, jump back to wherever we came from. - Stream.JumpToBit(CurrentBit); + if (Error JumpFailed = Stream.JumpToBit(CurrentBit)) + return JumpFailed; return Error::success(); case BitstreamEntry::Record: // The interesting case. @@ -5114,7 +5241,10 @@ Error ModuleSummaryIndexBitcodeReader::parseValueSymbolTable( // Read a record. Record.clear(); - switch (Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + switch (MaybeRecord.get()) { default: // Default behavior: ignore (e.g. VST_CODE_BBENTRY records). break; case bitc::VST_CODE_ENTRY: { // VST_CODE_ENTRY: [valueid, namechar x N] @@ -5162,8 +5292,8 @@ Error ModuleSummaryIndexBitcodeReader::parseValueSymbolTable( // At the end of this routine the module Index is populated with a map // from global value id to GlobalValueSummary objects. Error ModuleSummaryIndexBitcodeReader::parseModule() { - if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) + return Err; SmallVector<uint64_t, 64> Record; DenseMap<unsigned, GlobalValue::LinkageTypes> ValueIdToLinkageMap; @@ -5171,7 +5301,10 @@ Error ModuleSummaryIndexBitcodeReader::parseModule() { // Read the index for this module. while (true) { - BitstreamEntry Entry = Stream.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + llvm::BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::Error: @@ -5182,8 +5315,8 @@ Error ModuleSummaryIndexBitcodeReader::parseModule() { case BitstreamEntry::SubBlock: switch (Entry.ID) { default: // Skip unknown content. - if (Stream.SkipBlock()) - return error("Invalid record"); + if (Error Err = Stream.SkipBlock()) + return Err; break; case bitc::BLOCKINFO_BLOCK_ID: // Need to parse these to get abbrev ids (e.g. for VST) @@ -5196,8 +5329,8 @@ Error ModuleSummaryIndexBitcodeReader::parseModule() { assert(((SeenValueSymbolTable && VSTOffset > 0) || !SeenGlobalValSummary) && "Expected early VST parse via VSTOffset record"); - if (Stream.SkipBlock()) - return error("Invalid record"); + if (Error Err = Stream.SkipBlock()) + return Err; break; case bitc::GLOBALVAL_SUMMARY_BLOCK_ID: case bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID: @@ -5228,8 +5361,10 @@ Error ModuleSummaryIndexBitcodeReader::parseModule() { case BitstreamEntry::Record: { Record.clear(); - auto BitCode = Stream.readRecord(Entry.ID, Record); - switch (BitCode) { + Expected<unsigned> MaybeBitCode = Stream.readRecord(Entry.ID, Record); + if (!MaybeBitCode) + return MaybeBitCode.takeError(); + switch (unsigned BitCode = MaybeBitCode.get()) { default: break; // Default behavior, ignore unknown content. case bitc::MODULE_CODE_VERSION: { @@ -5386,16 +5521,23 @@ static void setImmutableRefs(std::vector<ValueInfo> &Refs, unsigned Count) { // Eagerly parse the entire summary block. This populates the GlobalValueSummary // objects in the index. Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { - if (Stream.EnterSubBlock(ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(ID)) + return Err; SmallVector<uint64_t, 64> Record; // Parse version { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); + if (Entry.Kind != BitstreamEntry::Record) return error("Invalid Summary Block: record for version expected"); - if (Stream.readRecord(Entry.ID, Record) != bitc::FS_VERSION) + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + if (MaybeRecord.get() != bitc::FS_VERSION) return error("Invalid Summary Block: version expected"); } const uint64_t Version = Record[0]; @@ -5420,7 +5562,10 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { PendingTypeCheckedLoadConstVCalls; while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -5441,8 +5586,10 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { // in the combined index VST entries). The records also contain // information used for ThinLTO renaming and importing. Record.clear(); - auto BitCode = Stream.readRecord(Entry.ID, Record); - switch (BitCode) { + Expected<unsigned> MaybeBitCode = Stream.readRecord(Entry.ID, Record); + if (!MaybeBitCode) + return MaybeBitCode.takeError(); + switch (unsigned BitCode = MaybeBitCode.get()) { default: // Default behavior: ignore. break; case bitc::FS_FLAGS: { // [flags] @@ -5765,8 +5912,8 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { // Parse the module string table block into the Index. // This populates the ModulePathStringTable map in the index. Error ModuleSummaryIndexBitcodeReader::parseModuleStringTable() { - if (Stream.EnterSubBlock(bitc::MODULE_STRTAB_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::MODULE_STRTAB_BLOCK_ID)) + return Err; SmallVector<uint64_t, 64> Record; @@ -5774,7 +5921,10 @@ Error ModuleSummaryIndexBitcodeReader::parseModuleStringTable() { ModuleSummaryIndex::ModuleInfo *LastSeenModule = nullptr; while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -5788,7 +5938,10 @@ Error ModuleSummaryIndexBitcodeReader::parseModuleStringTable() { } Record.clear(); - switch (Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + switch (MaybeRecord.get()) { default: // Default behavior: ignore. break; case bitc::MST_CODE_ENTRY: { @@ -5854,12 +6007,16 @@ const std::error_category &llvm::BitcodeErrorCategory() { static Expected<StringRef> readBlobInRecord(BitstreamCursor &Stream, unsigned Block, unsigned RecordID) { - if (Stream.EnterSubBlock(Block)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(Block)) + return std::move(Err); StringRef Strtab; while (true) { - BitstreamEntry Entry = Stream.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + llvm::BitstreamEntry Entry = MaybeEntry.get(); + switch (Entry.Kind) { case BitstreamEntry::EndBlock: return Strtab; @@ -5868,14 +6025,18 @@ static Expected<StringRef> readBlobInRecord(BitstreamCursor &Stream, return error("Malformed block"); case BitstreamEntry::SubBlock: - if (Stream.SkipBlock()) - return error("Malformed block"); + if (Error Err = Stream.SkipBlock()) + return std::move(Err); break; case BitstreamEntry::Record: StringRef Blob; SmallVector<uint64_t, 1> Record; - if (Stream.readRecord(Entry.ID, Record, &Blob) == RecordID) + Expected<unsigned> MaybeRecord = + Stream.readRecord(Entry.ID, Record, &Blob); + if (!MaybeRecord) + return MaybeRecord.takeError(); + if (MaybeRecord.get() == RecordID) Strtab = Blob; break; } @@ -5911,7 +6072,11 @@ llvm::getBitcodeFileContents(MemoryBufferRef Buffer) { if (BCBegin + 8 >= Stream.getBitcodeBytes().size()) return F; - BitstreamEntry Entry = Stream.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + llvm::BitstreamEntry Entry = MaybeEntry.get(); + switch (Entry.Kind) { case BitstreamEntry::EndBlock: case BitstreamEntry::Error: @@ -5921,10 +6086,16 @@ llvm::getBitcodeFileContents(MemoryBufferRef Buffer) { uint64_t IdentificationBit = -1ull; if (Entry.ID == bitc::IDENTIFICATION_BLOCK_ID) { IdentificationBit = Stream.GetCurrentBitNo() - BCBegin * 8; - if (Stream.SkipBlock()) - return error("Malformed block"); + if (Error Err = Stream.SkipBlock()) + return std::move(Err); + + { + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + Entry = MaybeEntry.get(); + } - Entry = Stream.advance(); if (Entry.Kind != BitstreamEntry::SubBlock || Entry.ID != bitc::MODULE_BLOCK_ID) return error("Malformed block"); @@ -5932,8 +6103,8 @@ llvm::getBitcodeFileContents(MemoryBufferRef Buffer) { if (Entry.ID == bitc::MODULE_BLOCK_ID) { uint64_t ModuleBit = Stream.GetCurrentBitNo() - BCBegin * 8; - if (Stream.SkipBlock()) - return error("Malformed block"); + if (Error Err = Stream.SkipBlock()) + return std::move(Err); F.Mods.push_back({Stream.getBitcodeBytes().slice( BCBegin, Stream.getCurrentByteNo() - BCBegin), @@ -5981,13 +6152,15 @@ llvm::getBitcodeFileContents(MemoryBufferRef Buffer) { continue; } - if (Stream.SkipBlock()) - return error("Malformed block"); + if (Error Err = Stream.SkipBlock()) + return std::move(Err); continue; } case BitstreamEntry::Record: - Stream.skipRecord(Entry.ID); - continue; + if (Expected<unsigned> StreamFailed = Stream.skipRecord(Entry.ID)) + continue; + else + return StreamFailed.takeError(); } } } @@ -6007,7 +6180,8 @@ BitcodeModule::getModuleImpl(LLVMContext &Context, bool MaterializeAll, std::string ProducerIdentification; if (IdentificationBit != -1ull) { - Stream.JumpToBit(IdentificationBit); + if (Error JumpFailed = Stream.JumpToBit(IdentificationBit)) + return std::move(JumpFailed); Expected<std::string> ProducerIdentificationOrErr = readIdentificationBlock(Stream); if (!ProducerIdentificationOrErr) @@ -6016,7 +6190,8 @@ BitcodeModule::getModuleImpl(LLVMContext &Context, bool MaterializeAll, ProducerIdentification = *ProducerIdentificationOrErr; } - Stream.JumpToBit(ModuleBit); + if (Error JumpFailed = Stream.JumpToBit(ModuleBit)) + return std::move(JumpFailed); auto *R = new BitcodeReader(std::move(Stream), Strtab, ProducerIdentification, Context); @@ -6054,7 +6229,8 @@ BitcodeModule::getLazyModule(LLVMContext &Context, bool ShouldLazyLoadMetadata, Error BitcodeModule::readSummary(ModuleSummaryIndex &CombinedIndex, StringRef ModulePath, uint64_t ModuleId) { BitstreamCursor Stream(Buffer); - Stream.JumpToBit(ModuleBit); + if (Error JumpFailed = Stream.JumpToBit(ModuleBit)) + return JumpFailed; ModuleSummaryIndexBitcodeReader R(std::move(Stream), Strtab, CombinedIndex, ModulePath, ModuleId); @@ -6064,7 +6240,8 @@ Error BitcodeModule::readSummary(ModuleSummaryIndex &CombinedIndex, // Parse the specified bitcode buffer, returning the function info index. Expected<std::unique_ptr<ModuleSummaryIndex>> BitcodeModule::getSummary() { BitstreamCursor Stream(Buffer); - Stream.JumpToBit(ModuleBit); + if (Error JumpFailed = Stream.JumpToBit(ModuleBit)) + return std::move(JumpFailed); auto Index = llvm::make_unique<ModuleSummaryIndex>(/*HaveGVs=*/false); ModuleSummaryIndexBitcodeReader R(std::move(Stream), Strtab, *Index, @@ -6078,12 +6255,15 @@ Expected<std::unique_ptr<ModuleSummaryIndex>> BitcodeModule::getSummary() { static Expected<bool> getEnableSplitLTOUnitFlag(BitstreamCursor &Stream, unsigned ID) { - if (Stream.EnterSubBlock(ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(ID)) + return std::move(Err); SmallVector<uint64_t, 64> Record; while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -6100,8 +6280,10 @@ static Expected<bool> getEnableSplitLTOUnitFlag(BitstreamCursor &Stream, // Look for the FS_FLAGS record. Record.clear(); - auto BitCode = Stream.readRecord(Entry.ID, Record); - switch (BitCode) { + Expected<unsigned> MaybeBitCode = Stream.readRecord(Entry.ID, Record); + if (!MaybeBitCode) + return MaybeBitCode.takeError(); + switch (MaybeBitCode.get()) { default: // Default behavior: ignore. break; case bitc::FS_FLAGS: { // [flags] @@ -6119,13 +6301,17 @@ static Expected<bool> getEnableSplitLTOUnitFlag(BitstreamCursor &Stream, // Check if the given bitcode buffer contains a global value summary block. Expected<BitcodeLTOInfo> BitcodeModule::getLTOInfo() { BitstreamCursor Stream(Buffer); - Stream.JumpToBit(ModuleBit); + if (Error JumpFailed = Stream.JumpToBit(ModuleBit)) + return std::move(JumpFailed); - if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) + return std::move(Err); while (true) { - BitstreamEntry Entry = Stream.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + llvm::BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::Error: @@ -6154,13 +6340,15 @@ Expected<BitcodeLTOInfo> BitcodeModule::getLTOInfo() { } // Ignore other sub-blocks. - if (Stream.SkipBlock()) - return error("Malformed block"); + if (Error Err = Stream.SkipBlock()) + return std::move(Err); continue; case BitstreamEntry::Record: - Stream.skipRecord(Entry.ID); - continue; + if (Expected<unsigned> StreamFailed = Stream.skipRecord(Entry.ID)) + continue; + else + return StreamFailed.takeError(); } } } diff --git a/llvm/lib/Bitcode/Reader/BitstreamReader.cpp b/llvm/lib/Bitcode/Reader/BitstreamReader.cpp index 985944738cb..2f29ce29db0 100644 --- a/llvm/lib/Bitcode/Reader/BitstreamReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitstreamReader.cpp @@ -17,9 +17,8 @@ using namespace llvm; // BitstreamCursor implementation //===----------------------------------------------------------------------===// -/// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter -/// the block, and return true if the block has an error. -bool BitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) { +/// Having read the ENTER_SUBBLOCK abbrevid, enter the block. +Error BitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) { // Save the current block's state on BlockScope. BlockScope.push_back(Block(CurCodeSize)); BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); @@ -34,21 +33,39 @@ bool BitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) { } // Get the codesize of this block. - CurCodeSize = ReadVBR(bitc::CodeLenWidth); - // We can't read more than MaxChunkSize at a time + Expected<uint32_t> MaybeVBR = ReadVBR(bitc::CodeLenWidth); + if (!MaybeVBR) + return MaybeVBR.takeError(); + CurCodeSize = MaybeVBR.get(); + if (CurCodeSize > MaxChunkSize) - return true; + return llvm::createStringError( + std::errc::illegal_byte_sequence, + "can't read more than %zu at a time, trying to read %u", +MaxChunkSize, + CurCodeSize); SkipToFourByteBoundary(); - unsigned NumWords = Read(bitc::BlockSizeWidth); - if (NumWordsP) *NumWordsP = NumWords; - - // Validate that this block is sane. - return CurCodeSize == 0 || AtEndOfStream(); + Expected<word_t> MaybeNum = Read(bitc::BlockSizeWidth); + if (!MaybeNum) + return MaybeNum.takeError(); + word_t NumWords = MaybeNum.get(); + if (NumWordsP) + *NumWordsP = NumWords; + + if (CurCodeSize == 0) + return llvm::createStringError( + std::errc::illegal_byte_sequence, + "can't enter sub-block: current code size is 0"); + if (AtEndOfStream()) + return llvm::createStringError( + std::errc::illegal_byte_sequence, + "can't enter sub block: already at end of stream"); + + return Error::success(); } -static uint64_t readAbbreviatedField(BitstreamCursor &Cursor, - const BitCodeAbbrevOp &Op) { +static Expected<uint64_t> readAbbreviatedField(BitstreamCursor &Cursor, + const BitCodeAbbrevOp &Op) { assert(!Op.isLiteral() && "Not to be used with literals!"); // Decode the value as we are commanded. @@ -63,13 +80,16 @@ static uint64_t readAbbreviatedField(BitstreamCursor &Cursor, assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize); return Cursor.ReadVBR64((unsigned)Op.getEncodingData()); case BitCodeAbbrevOp::Char6: - return BitCodeAbbrevOp::DecodeChar6(Cursor.Read(6)); + if (Expected<unsigned> Res = Cursor.Read(6)) + return BitCodeAbbrevOp::DecodeChar6(Res.get()); + else + return Res.takeError(); } llvm_unreachable("invalid abbreviation encoding"); } -static void skipAbbreviatedField(BitstreamCursor &Cursor, - const BitCodeAbbrevOp &Op) { +static Error skipAbbreviatedField(BitstreamCursor &Cursor, + const BitCodeAbbrevOp &Op) { assert(!Op.isLiteral() && "Not to be used with literals!"); // Decode the value as we are commanded. @@ -79,26 +99,43 @@ static void skipAbbreviatedField(BitstreamCursor &Cursor, llvm_unreachable("Should not reach here"); case BitCodeAbbrevOp::Fixed: assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize); - Cursor.Read((unsigned)Op.getEncodingData()); - break; + if (Expected<unsigned> Res = Cursor.Read((unsigned)Op.getEncodingData())) + break; + else + return Res.takeError(); case BitCodeAbbrevOp::VBR: assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize); - Cursor.ReadVBR64((unsigned)Op.getEncodingData()); - break; + if (Expected<uint64_t> Res = + Cursor.ReadVBR64((unsigned)Op.getEncodingData())) + break; + else + return Res.takeError(); case BitCodeAbbrevOp::Char6: - Cursor.Read(6); - break; + if (Expected<unsigned> Res = Cursor.Read(6)) + break; + else + return Res.takeError(); } + return ErrorSuccess(); } /// skipRecord - Read the current record and discard it. -unsigned BitstreamCursor::skipRecord(unsigned AbbrevID) { +Expected<unsigned> BitstreamCursor::skipRecord(unsigned AbbrevID) { // Skip unabbreviated records by reading past their entries. if (AbbrevID == bitc::UNABBREV_RECORD) { - unsigned Code = ReadVBR(6); - unsigned NumElts = ReadVBR(6); + Expected<uint32_t> MaybeCode = ReadVBR(6); + if (!MaybeCode) + return MaybeCode.takeError(); + unsigned Code = MaybeCode.get(); + Expected<uint32_t> MaybeVBR = ReadVBR(6); + if (!MaybeVBR) + return MaybeVBR.get(); + unsigned NumElts = MaybeVBR.get(); for (unsigned i = 0; i != NumElts; ++i) - (void)ReadVBR64(6); + if (Expected<uint64_t> Res = ReadVBR64(6)) + ; // Skip! + else + return Res.takeError(); return Code; } @@ -110,8 +147,13 @@ unsigned BitstreamCursor::skipRecord(unsigned AbbrevID) { else { if (CodeOp.getEncoding() == BitCodeAbbrevOp::Array || CodeOp.getEncoding() == BitCodeAbbrevOp::Blob) - report_fatal_error("Abbreviation starts with an Array or a Blob"); - Code = readAbbreviatedField(*this, CodeOp); + return llvm::createStringError( + std::errc::illegal_byte_sequence, + "Abbreviation starts with an Array or a Blob"); + Expected<uint64_t> MaybeCode = readAbbreviatedField(*this, CodeOp); + if (!MaybeCode) + return MaybeCode.takeError(); + Code = MaybeCode.get(); } for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i < e; ++i) { @@ -121,13 +163,17 @@ unsigned BitstreamCursor::skipRecord(unsigned AbbrevID) { if (Op.getEncoding() != BitCodeAbbrevOp::Array && Op.getEncoding() != BitCodeAbbrevOp::Blob) { - skipAbbreviatedField(*this, Op); + if (Error Err = skipAbbreviatedField(*this, Op)) + return std::move(Err); continue; } if (Op.getEncoding() == BitCodeAbbrevOp::Array) { // Array case. Read the number of elements as a vbr6. - unsigned NumElts = ReadVBR(6); + Expected<uint32_t> MaybeNum = ReadVBR(6); + if (!MaybeNum) + return MaybeNum.takeError(); + unsigned NumElts = MaybeNum.get(); // Get the element encoding. assert(i+2 == e && "array op not second to last?"); @@ -140,15 +186,22 @@ unsigned BitstreamCursor::skipRecord(unsigned AbbrevID) { report_fatal_error("Array element type can't be an Array or a Blob"); case BitCodeAbbrevOp::Fixed: assert((unsigned)EltEnc.getEncodingData() <= MaxChunkSize); - JumpToBit(GetCurrentBitNo() + NumElts * EltEnc.getEncodingData()); + if (Error Err = JumpToBit(GetCurrentBitNo() + + NumElts * EltEnc.getEncodingData())) + return std::move(Err); break; case BitCodeAbbrevOp::VBR: assert((unsigned)EltEnc.getEncodingData() <= MaxChunkSize); for (; NumElts; --NumElts) - ReadVBR64((unsigned)EltEnc.getEncodingData()); + if (Expected<uint64_t> Res = + ReadVBR64((unsigned)EltEnc.getEncodingData())) + ; // Skip! + else + return Res.takeError(); break; case BitCodeAbbrevOp::Char6: - JumpToBit(GetCurrentBitNo() + NumElts * 6); + if (Error Err = JumpToBit(GetCurrentBitNo() + NumElts * 6)) + return std::move(Err); break; } continue; @@ -156,7 +209,10 @@ unsigned BitstreamCursor::skipRecord(unsigned AbbrevID) { assert(Op.getEncoding() == BitCodeAbbrevOp::Blob); // Blob case. Read the number of bytes as a vbr6. - unsigned NumElts = ReadVBR(6); + Expected<uint32_t> MaybeNum = ReadVBR(6); + if (!MaybeNum) + return MaybeNum.takeError(); + unsigned NumElts = MaybeNum.get(); SkipToFourByteBoundary(); // 32-bit alignment // Figure out where the end of this blob will be including tail padding. @@ -170,19 +226,30 @@ unsigned BitstreamCursor::skipRecord(unsigned AbbrevID) { } // Skip over the blob. - JumpToBit(NewEnd); + if (Error Err = JumpToBit(NewEnd)) + return std::move(Err); } return Code; } -unsigned BitstreamCursor::readRecord(unsigned AbbrevID, - SmallVectorImpl<uint64_t> &Vals, - StringRef *Blob) { +Expected<unsigned> BitstreamCursor::readRecord(unsigned AbbrevID, + SmallVectorImpl<uint64_t> &Vals, + StringRef *Blob) { if (AbbrevID == bitc::UNABBREV_RECORD) { - unsigned Code = ReadVBR(6); - unsigned NumElts = ReadVBR(6); + Expected<uint32_t> MaybeCode = ReadVBR(6); + if (!MaybeCode) + return MaybeCode.takeError(); + uint32_t Code = MaybeCode.get(); + Expected<uint32_t> MaybeNumElts = ReadVBR(6); + if (!MaybeNumElts) + return MaybeNumElts.takeError(); + uint32_t NumElts = MaybeNumElts.get(); + for (unsigned i = 0; i != NumElts; ++i) - Vals.push_back(ReadVBR64(6)); + if (Expected<uint64_t> MaybeVal = ReadVBR64(6)) + Vals.push_back(MaybeVal.get()); + else + return MaybeVal.takeError(); return Code; } @@ -198,7 +265,10 @@ unsigned BitstreamCursor::readRecord(unsigned AbbrevID, if (CodeOp.getEncoding() == BitCodeAbbrevOp::Array || CodeOp.getEncoding() == BitCodeAbbrevOp::Blob) report_fatal_error("Abbreviation starts with an Array or a Blob"); - Code = readAbbreviatedField(*this, CodeOp); + if (Expected<uint64_t> MaybeCode = readAbbreviatedField(*this, CodeOp)) + Code = MaybeCode.get(); + else + return MaybeCode.takeError(); } for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i != e; ++i) { @@ -210,13 +280,19 @@ unsigned BitstreamCursor::readRecord(unsigned AbbrevID, if (Op.getEncoding() != BitCodeAbbrevOp::Array && Op.getEncoding() != BitCodeAbbrevOp::Blob) { - Vals.push_back(readAbbreviatedField(*this, Op)); + if (Expected<uint64_t> MaybeVal = readAbbreviatedField(*this, Op)) + Vals.push_back(MaybeVal.get()); + else + return MaybeVal.takeError(); continue; } if (Op.getEncoding() == BitCodeAbbrevOp::Array) { // Array case. Read the number of elements as a vbr6. - unsigned NumElts = ReadVBR(6); + Expected<uint32_t> MaybeNumElts = ReadVBR(6); + if (!MaybeNumElts) + return MaybeNumElts.takeError(); + uint32_t NumElts = MaybeNumElts.get(); // Get the element encoding. if (i + 2 != e) @@ -232,22 +308,36 @@ unsigned BitstreamCursor::readRecord(unsigned AbbrevID, report_fatal_error("Array element type can't be an Array or a Blob"); case BitCodeAbbrevOp::Fixed: for (; NumElts; --NumElts) - Vals.push_back(Read((unsigned)EltEnc.getEncodingData())); + if (Expected<SimpleBitstreamCursor::word_t> MaybeVal = + Read((unsigned)EltEnc.getEncodingData())) + Vals.push_back(MaybeVal.get()); + else + return MaybeVal.takeError(); break; case BitCodeAbbrevOp::VBR: for (; NumElts; --NumElts) - Vals.push_back(ReadVBR64((unsigned)EltEnc.getEncodingData())); + if (Expected<uint64_t> MaybeVal = + ReadVBR64((unsigned)EltEnc.getEncodingData())) + Vals.push_back(MaybeVal.get()); + else + return MaybeVal.takeError(); break; case BitCodeAbbrevOp::Char6: for (; NumElts; --NumElts) - Vals.push_back(BitCodeAbbrevOp::DecodeChar6(Read(6))); + if (Expected<SimpleBitstreamCursor::word_t> MaybeVal = Read(6)) + Vals.push_back(BitCodeAbbrevOp::DecodeChar6(MaybeVal.get())); + else + return MaybeVal.takeError(); } continue; } assert(Op.getEncoding() == BitCodeAbbrevOp::Blob); // Blob case. Read the number of bytes as a vbr6. - unsigned NumElts = ReadVBR(6); + Expected<uint32_t> MaybeNumElts = ReadVBR(6); + if (!MaybeNumElts) + return MaybeNumElts.takeError(); + uint32_t NumElts = MaybeNumElts.get(); SkipToFourByteBoundary(); // 32-bit alignment // Figure out where the end of this blob will be including tail padding. @@ -265,7 +355,8 @@ unsigned BitstreamCursor::readRecord(unsigned AbbrevID, // Otherwise, inform the streamer that we need these bytes in memory. Skip // over tail padding first, in case jumping to NewEnd invalidates the Blob // pointer. - JumpToBit(NewEnd); + if (Error Err = JumpToBit(NewEnd)) + return std::move(Err); const char *Ptr = (const char *)getPointerToBit(CurBitPos, NumElts); // If we can return a reference to the data, do so to avoid copying it. @@ -281,19 +372,35 @@ unsigned BitstreamCursor::readRecord(unsigned AbbrevID, return Code; } -void BitstreamCursor::ReadAbbrevRecord() { +Error BitstreamCursor::ReadAbbrevRecord() { auto Abbv = std::make_shared<BitCodeAbbrev>(); - unsigned NumOpInfo = ReadVBR(5); + Expected<uint32_t> MaybeNumOpInfo = ReadVBR(5); + if (!MaybeNumOpInfo) + return MaybeNumOpInfo.takeError(); + unsigned NumOpInfo = MaybeNumOpInfo.get(); for (unsigned i = 0; i != NumOpInfo; ++i) { - bool IsLiteral = Read(1); + Expected<word_t> MaybeIsLiteral = Read(1); + if (!MaybeIsLiteral) + return MaybeIsLiteral.takeError(); + bool IsLiteral = MaybeIsLiteral.get(); if (IsLiteral) { - Abbv->Add(BitCodeAbbrevOp(ReadVBR64(8))); + Expected<uint64_t> MaybeOp = ReadVBR64(8); + if (!MaybeOp) + return MaybeOp.takeError(); + Abbv->Add(BitCodeAbbrevOp(MaybeOp.get())); continue; } - BitCodeAbbrevOp::Encoding E = (BitCodeAbbrevOp::Encoding)Read(3); + Expected<word_t> MaybeEncoding = Read(3); + if (!MaybeEncoding) + return MaybeEncoding.takeError(); + BitCodeAbbrevOp::Encoding E = + (BitCodeAbbrevOp::Encoding)MaybeEncoding.get(); if (BitCodeAbbrevOp::hasEncodingData(E)) { - uint64_t Data = ReadVBR64(5); + Expected<uint64_t> MaybeData = ReadVBR64(5); + if (!MaybeData) + return MaybeData.takeError(); + uint64_t Data = MaybeData.get(); // As a special case, handle fixed(0) (i.e., a fixed field with zero bits) // and vbr(0) as a literal zero. This is decoded the same way, and avoids @@ -317,11 +424,14 @@ void BitstreamCursor::ReadAbbrevRecord() { if (Abbv->getNumOperandInfos() == 0) report_fatal_error("Abbrev record with no operands"); CurAbbrevs.push_back(std::move(Abbv)); + + return Error::success(); } -Optional<BitstreamBlockInfo> +Expected<Optional<BitstreamBlockInfo>> BitstreamCursor::ReadBlockInfoBlock(bool ReadBlockInfoNames) { - if (EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID)) return None; + if (llvm::Error Err = EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID)) + return std::move(Err); BitstreamBlockInfo NewBlockInfo; @@ -330,7 +440,11 @@ BitstreamCursor::ReadBlockInfoBlock(bool ReadBlockInfoNames) { // Read all the records for this module. while (true) { - BitstreamEntry Entry = advanceSkippingSubblocks(AF_DontAutoprocessAbbrevs); + Expected<BitstreamEntry> MaybeEntry = + advanceSkippingSubblocks(AF_DontAutoprocessAbbrevs); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case llvm::BitstreamEntry::SubBlock: // Handled for us already. @@ -346,7 +460,8 @@ BitstreamCursor::ReadBlockInfoBlock(bool ReadBlockInfoNames) { // Read abbrev records, associate them with CurBID. if (Entry.ID == bitc::DEFINE_ABBREV) { if (!CurBlockInfo) return None; - ReadAbbrevRecord(); + if (Error Err = ReadAbbrevRecord()) + return std::move(Err); // ReadAbbrevRecord installs the abbrev in CurAbbrevs. Move it to the // appropriate BlockInfo. @@ -357,22 +472,28 @@ BitstreamCursor::ReadBlockInfoBlock(bool ReadBlockInfoNames) { // Read a record. Record.clear(); - switch (readRecord(Entry.ID, Record)) { - default: break; // Default behavior, ignore unknown content. - case bitc::BLOCKINFO_CODE_SETBID: - if (Record.size() < 1) return None; - CurBlockInfo = &NewBlockInfo.getOrCreateBlockInfo((unsigned)Record[0]); - break; - case bitc::BLOCKINFO_CODE_BLOCKNAME: { - if (!CurBlockInfo) return None; - if (!ReadBlockInfoNames) - break; // Ignore name. - std::string Name; - for (unsigned i = 0, e = Record.size(); i != e; ++i) - Name += (char)Record[i]; - CurBlockInfo->Name = Name; - break; - } + Expected<unsigned> MaybeBlockInfo = readRecord(Entry.ID, Record); + if (!MaybeBlockInfo) + return MaybeBlockInfo.takeError(); + switch (MaybeBlockInfo.get()) { + default: + break; // Default behavior, ignore unknown content. + case bitc::BLOCKINFO_CODE_SETBID: + if (Record.size() < 1) + return None; + CurBlockInfo = &NewBlockInfo.getOrCreateBlockInfo((unsigned)Record[0]); + break; + case bitc::BLOCKINFO_CODE_BLOCKNAME: { + if (!CurBlockInfo) + return None; + if (!ReadBlockInfoNames) + break; // Ignore name. + std::string Name; + for (unsigned i = 0, e = Record.size(); i != e; ++i) + Name += (char)Record[i]; + CurBlockInfo->Name = Name; + break; + } case bitc::BLOCKINFO_CODE_SETRECORDNAME: { if (!CurBlockInfo) return None; if (!ReadBlockInfoNames) @@ -384,6 +505,6 @@ BitstreamCursor::ReadBlockInfoBlock(bool ReadBlockInfoNames) { Name)); break; } - } + } } } diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index a0588aa361c..03f9c950ef0 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -674,8 +674,12 @@ MetadataLoader::MetadataLoaderImpl::lazyLoadModuleMetadataBlock() { SmallVector<uint64_t, 64> Record; // Get the abbrevs, and preload record positions to make them lazy-loadable. while (true) { - BitstreamEntry Entry = IndexCursor.advanceSkippingSubblocks( + Expected<BitstreamEntry> MaybeEntry = IndexCursor.advanceSkippingSubblocks( BitstreamCursor::AF_DontPopBlockAtEnd); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); + switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. case BitstreamEntry::Error: @@ -687,14 +691,22 @@ MetadataLoader::MetadataLoaderImpl::lazyLoadModuleMetadataBlock() { // The interesting case. ++NumMDRecordLoaded; uint64_t CurrentPos = IndexCursor.GetCurrentBitNo(); - auto Code = IndexCursor.skipRecord(Entry.ID); + Expected<unsigned> MaybeCode = IndexCursor.skipRecord(Entry.ID); + if (!MaybeCode) + return MaybeCode.takeError(); + unsigned Code = MaybeCode.get(); switch (Code) { case bitc::METADATA_STRINGS: { // Rewind and parse the strings. - IndexCursor.JumpToBit(CurrentPos); + if (Error Err = IndexCursor.JumpToBit(CurrentPos)) + return std::move(Err); StringRef Blob; Record.clear(); - IndexCursor.readRecord(Entry.ID, Record, &Blob); + if (Expected<unsigned> MaybeRecord = + IndexCursor.readRecord(Entry.ID, Record, &Blob)) + ; + else + return MaybeRecord.takeError(); unsigned NumStrings = Record[0]; MDStringRef.reserve(NumStrings); auto IndexNextMDString = [&](StringRef Str) { @@ -707,26 +719,37 @@ MetadataLoader::MetadataLoaderImpl::lazyLoadModuleMetadataBlock() { case bitc::METADATA_INDEX_OFFSET: { // This is the offset to the index, when we see this we skip all the // records and load only an index to these. - IndexCursor.JumpToBit(CurrentPos); + if (Error Err = IndexCursor.JumpToBit(CurrentPos)) + return std::move(Err); Record.clear(); - IndexCursor.readRecord(Entry.ID, Record); + if (Expected<unsigned> MaybeRecord = + IndexCursor.readRecord(Entry.ID, Record)) + ; + else + return MaybeRecord.takeError(); if (Record.size() != 2) return error("Invalid record"); auto Offset = Record[0] + (Record[1] << 32); auto BeginPos = IndexCursor.GetCurrentBitNo(); - IndexCursor.JumpToBit(BeginPos + Offset); - Entry = IndexCursor.advanceSkippingSubblocks( - BitstreamCursor::AF_DontPopBlockAtEnd); + if (Error Err = IndexCursor.JumpToBit(BeginPos + Offset)) + return std::move(Err); + Expected<BitstreamEntry> MaybeEntry = + IndexCursor.advanceSkippingSubblocks( + BitstreamCursor::AF_DontPopBlockAtEnd); + if (!MaybeEntry) + return MaybeEntry.takeError(); + Entry = MaybeEntry.get(); assert(Entry.Kind == BitstreamEntry::Record && "Corrupted bitcode: Expected `Record` when trying to find the " "Metadata index"); Record.clear(); - auto Code = IndexCursor.readRecord(Entry.ID, Record); - (void)Code; - assert(Code == bitc::METADATA_INDEX && "Corrupted bitcode: Expected " - "`METADATA_INDEX` when trying " - "to find the Metadata index"); - + if (Expected<unsigned> MaybeCode = + IndexCursor.readRecord(Entry.ID, Record)) + assert(MaybeCode.get() == bitc::METADATA_INDEX && + "Corrupted bitcode: Expected `METADATA_INDEX` when trying to " + "find the Metadata index"); + else + return MaybeCode.takeError(); // Delta unpack auto CurrentValue = BeginPos; GlobalMetadataBitPosIndex.reserve(Record.size()); @@ -742,21 +765,33 @@ MetadataLoader::MetadataLoaderImpl::lazyLoadModuleMetadataBlock() { return error("Corrupted Metadata block"); case bitc::METADATA_NAME: { // Named metadata need to be materialized now and aren't deferred. - IndexCursor.JumpToBit(CurrentPos); + if (Error Err = IndexCursor.JumpToBit(CurrentPos)) + return std::move(Err); Record.clear(); - unsigned Code = IndexCursor.readRecord(Entry.ID, Record); - assert(Code == bitc::METADATA_NAME); + + unsigned Code; + if (Expected<unsigned> MaybeCode = + IndexCursor.readRecord(Entry.ID, Record)) { + Code = MaybeCode.get(); + assert(Code == bitc::METADATA_NAME); + } else + return MaybeCode.takeError(); // Read name of the named metadata. SmallString<8> Name(Record.begin(), Record.end()); - Code = IndexCursor.ReadCode(); + if (Expected<unsigned> MaybeCode = IndexCursor.ReadCode()) + Code = MaybeCode.get(); + else + return MaybeCode.takeError(); // Named Metadata comes in two parts, we expect the name to be followed // by the node Record.clear(); - unsigned NextBitCode = IndexCursor.readRecord(Code, Record); - assert(NextBitCode == bitc::METADATA_NAMED_NODE); - (void)NextBitCode; + if (Expected<unsigned> MaybeNextBitCode = + IndexCursor.readRecord(Code, Record)) + assert(MaybeNextBitCode.get() == bitc::METADATA_NAMED_NODE); + else + return MaybeNextBitCode.takeError(); // Read named metadata elements. unsigned Size = Record.size(); @@ -775,9 +810,14 @@ MetadataLoader::MetadataLoaderImpl::lazyLoadModuleMetadataBlock() { case bitc::METADATA_GLOBAL_DECL_ATTACHMENT: { // FIXME: we need to do this early because we don't materialize global // value explicitly. - IndexCursor.JumpToBit(CurrentPos); + if (Error Err = IndexCursor.JumpToBit(CurrentPos)) + return std::move(Err); Record.clear(); - IndexCursor.readRecord(Entry.ID, Record); + if (Expected<unsigned> MaybeRecord = + IndexCursor.readRecord(Entry.ID, Record)) + ; + else + return MaybeRecord.takeError(); if (Record.size() % 2 == 0) return error("Invalid record"); unsigned ValueID = Record[0]; @@ -845,8 +885,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel) { // skip the whole block in case we lazy-load. auto EntryPos = Stream.GetCurrentBitNo(); - if (Stream.EnterSubBlock(bitc::METADATA_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::METADATA_BLOCK_ID)) + return Err; SmallVector<uint64_t, 64> Record; PlaceholderQueue Placeholders; @@ -871,9 +911,14 @@ Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel) { // Return at the beginning of the block, since it is easy to skip it // entirely from there. Stream.ReadBlockEnd(); // Pop the abbrev block context. - Stream.JumpToBit(EntryPos); - if (Stream.SkipBlock()) - return error("Invalid record"); + if (Error Err = IndexCursor.JumpToBit(EntryPos)) + return Err; + if (Error Err = Stream.SkipBlock()) { + // FIXME this drops the error on the floor, which + // ThinLTO/X86/debuginfo-cu-import.ll relies on. + consumeError(std::move(Err)); + return Error::success(); + } return Error::success(); } // Couldn't load an index, fallback to loading all the block "old-style". @@ -883,7 +928,10 @@ Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel) { // Read all the records. while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -902,10 +950,13 @@ Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel) { Record.clear(); StringRef Blob; ++NumMDRecordLoaded; - unsigned Code = Stream.readRecord(Entry.ID, Record, &Blob); - if (Error Err = - parseOneMetadata(Record, Code, Placeholders, Blob, NextMetadataNo)) - return Err; + if (Expected<unsigned> MaybeCode = + Stream.readRecord(Entry.ID, Record, &Blob)) { + if (Error Err = parseOneMetadata(Record, MaybeCode.get(), Placeholders, + Blob, NextMetadataNo)) + return Err; + } else + return MaybeCode.takeError(); } } @@ -930,12 +981,25 @@ void MetadataLoader::MetadataLoaderImpl::lazyLoadOneMetadata( } SmallVector<uint64_t, 64> Record; StringRef Blob; - IndexCursor.JumpToBit(GlobalMetadataBitPosIndex[ID - MDStringRef.size()]); - auto Entry = IndexCursor.advanceSkippingSubblocks(); + if (Error Err = IndexCursor.JumpToBit( + GlobalMetadataBitPosIndex[ID - MDStringRef.size()])) + report_fatal_error("lazyLoadOneMetadata failed jumping: " + + toString(std::move(Err))); + Expected<BitstreamEntry> MaybeEntry = IndexCursor.advanceSkippingSubblocks(); + if (!MaybeEntry) + // FIXME this drops the error on the floor. + report_fatal_error("lazyLoadOneMetadata failed advanceSkippingSubblocks: " + + toString(MaybeEntry.takeError())); + BitstreamEntry Entry = MaybeEntry.get(); ++NumMDRecordLoaded; - unsigned Code = IndexCursor.readRecord(Entry.ID, Record, &Blob); - if (Error Err = parseOneMetadata(Record, Code, Placeholders, Blob, ID)) - report_fatal_error("Can't lazyload MD"); + if (Expected<unsigned> MaybeCode = + IndexCursor.readRecord(Entry.ID, Record, &Blob)) { + if (Error Err = + parseOneMetadata(Record, MaybeCode.get(), Placeholders, Blob, ID)) + report_fatal_error("Can't lazyload MD, parseOneMetadata: " + + toString(std::move(Err))); + } else + report_fatal_error("Can't lazyload MD: " + toString(MaybeCode.takeError())); } /// Ensure that all forward-references and placeholders are resolved. @@ -1032,12 +1096,17 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( // Read name of the named metadata. SmallString<8> Name(Record.begin(), Record.end()); Record.clear(); - Code = Stream.ReadCode(); + Expected<unsigned> MaybeCode = Stream.ReadCode(); + if (!MaybeCode) + return MaybeCode.takeError(); + Code = MaybeCode.get(); ++NumMDRecordLoaded; - unsigned NextBitCode = Stream.readRecord(Code, Record); - if (NextBitCode != bitc::METADATA_NAMED_NODE) - return error("METADATA_NAME not followed by METADATA_NAMED_NODE"); + if (Expected<unsigned> MaybeNextBitCode = Stream.readRecord(Code, Record)) { + if (MaybeNextBitCode.get() != bitc::METADATA_NAMED_NODE) + return error("METADATA_NAME not followed by METADATA_NAMED_NODE"); + } else + return MaybeNextBitCode.takeError(); // Read named metadata elements. unsigned Size = Record.size(); @@ -1863,7 +1932,10 @@ Error MetadataLoader::MetadataLoaderImpl::parseMetadataStrings( if (R.AtEndOfStream()) return error("Invalid record: metadata strings bad length"); - unsigned Size = R.ReadVBR(6); + Expected<uint32_t> MaybeSize = R.ReadVBR(6); + if (!MaybeSize) + return MaybeSize.takeError(); + uint32_t Size = MaybeSize.get(); if (Strings.size() < Size) return error("Invalid record: metadata strings truncated chars"); @@ -1892,14 +1964,17 @@ Error MetadataLoader::MetadataLoaderImpl::parseGlobalObjectAttachment( /// Parse metadata attachments. Error MetadataLoader::MetadataLoaderImpl::parseMetadataAttachment( Function &F, const SmallVectorImpl<Instruction *> &InstructionList) { - if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID)) + return Err; SmallVector<uint64_t, 64> Record; PlaceholderQueue Placeholders; while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -1916,7 +1991,10 @@ Error MetadataLoader::MetadataLoaderImpl::parseMetadataAttachment( // Read a metadata attachment record. Record.clear(); ++NumMDRecordLoaded; - switch (Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecord) + return MaybeRecord.takeError(); + switch (MaybeRecord.get()) { default: // Default behavior: ignore. break; case bitc::METADATA_ATTACHMENT: { @@ -1990,14 +2068,17 @@ Error MetadataLoader::MetadataLoaderImpl::parseMetadataKindRecord( /// Parse the metadata kinds out of the METADATA_KIND_BLOCK. Error MetadataLoader::MetadataLoaderImpl::parseMetadataKinds() { - if (Stream.EnterSubBlock(bitc::METADATA_KIND_BLOCK_ID)) - return error("Invalid record"); + if (Error Err = Stream.EnterSubBlock(bitc::METADATA_KIND_BLOCK_ID)) + return Err; SmallVector<uint64_t, 64> Record; // Read all the records. while (true) { - BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<BitstreamEntry> MaybeEntry = Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case BitstreamEntry::SubBlock: // Handled for us already. @@ -2013,8 +2094,10 @@ Error MetadataLoader::MetadataLoaderImpl::parseMetadataKinds() { // Read a record. Record.clear(); ++NumMDRecordLoaded; - unsigned Code = Stream.readRecord(Entry.ID, Record); - switch (Code) { + Expected<unsigned> MaybeCode = Stream.readRecord(Entry.ID, Record); + if (!MaybeCode) + return MaybeCode.takeError(); + switch (MaybeCode.get()) { default: // Default behavior: ignore. break; case bitc::METADATA_KIND: { |