Index: lld/COFF/PDB.cpp =================================================================== --- lld/COFF/PDB.cpp +++ lld/COFF/PDB.cpp @@ -96,8 +96,8 @@ msf::StreamReader Reader(Stream); if (auto EC = Reader.readArray(Types, Reader.getLength())) fatal(EC, "Reader::readArray failed"); - if (!codeview::mergeTypeStreams(Builder, Types)) - fatal("codeview::mergeTypeStreams failed"); + if (auto Err = codeview::mergeTypeStreams(Builder, Types)) + fatal(Err, "codeview::mergeTypeStreams failed"); } // Construct section contents. Index: llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h =================================================================== --- llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h +++ llvm/include/llvm/DebugInfo/CodeView/TypeStreamMerger.h @@ -13,12 +13,13 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" +#include "llvm/Support/Error.h" namespace llvm { namespace codeview { /// Merges one type stream into another. Returns true on success. -bool mergeTypeStreams(TypeTableBuilder &DestStream, const CVTypeArray &Types); +Error mergeTypeStreams(TypeTableBuilder &DestStream, const CVTypeArray &Types); } // end namespace codeview } // end namespace llvm Index: llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp =================================================================== --- llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp +++ llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp @@ -56,7 +56,10 @@ public: TypeStreamMerger(TypeTableBuilder &DestStream) : DestStream(DestStream), FieldListBuilder(DestStream) { - assert(!hadError()); + // The initial value of LastError have no significance, + // but we still need to set its internal "isChecked" flag. + // Otherwise it will raise a runtime error. So we do that here. + (void)static_cast(LastError); } /// TypeVisitorCallbacks overrides. @@ -74,12 +77,15 @@ Error visitTypeEnd(CVType &Record) override; Error visitMemberEnd(CVMemberRecord &Record) override; - bool mergeStream(const CVTypeArray &Types); + Error mergeStream(const CVTypeArray &Types); private: template Error visitKnownRecordImpl(RecordType &Record) { - FoundBadTypeIndex |= !Record.remapTypeIndices(IndexMap); + if (!Record.remapTypeIndices(IndexMap)) + LastError = joinErrors( + std::move(LastError), + llvm::make_error(cv_error_code::corrupt_record)); IndexMap.push_back(DestStream.writeKnownType(Record)); return Error::success(); } @@ -94,14 +100,15 @@ template Error visitKnownMemberRecordImpl(RecordType &Record) { - FoundBadTypeIndex |= !Record.remapTypeIndices(IndexMap); + if (!Record.remapTypeIndices(IndexMap)) + LastError = joinErrors( + std::move(LastError), + llvm::make_error(cv_error_code::corrupt_record)); FieldListBuilder.writeMemberType(Record); return Error::success(); } - bool hadError() { return FoundBadTypeIndex; } - - bool FoundBadTypeIndex = false; + Error LastError = Error::success(); BumpPtrAllocator Allocator; @@ -163,9 +170,10 @@ return llvm::make_error(cv_error_code::corrupt_record); } -bool TypeStreamMerger::mergeStream(const CVTypeArray &Types) { +Error TypeStreamMerger::mergeStream(const CVTypeArray &Types) { assert(IndexMap.empty()); TypeVisitorCallbackPipeline Pipeline; + LastError = Error::success(); TypeDeserializer Deserializer; Pipeline.addCallbackToPipeline(Deserializer); @@ -173,15 +181,14 @@ CVTypeVisitor Visitor(Pipeline); - if (auto EC = Visitor.visitTypeStream(Types)) { - consumeError(std::move(EC)); - return false; - } + if (auto EC = Visitor.visitTypeStream(Types)) + return EC; IndexMap.clear(); - return !hadError(); + + return std::move(LastError); } -bool llvm::codeview::mergeTypeStreams(TypeTableBuilder &DestStream, - const CVTypeArray &Types) { +Error llvm::codeview::mergeTypeStreams(TypeTableBuilder &DestStream, + const CVTypeArray &Types) { return TypeStreamMerger(DestStream).mergeStream(Types); }