Index: COFF/DriverUtils.cpp =================================================================== --- COFF/DriverUtils.cpp +++ COFF/DriverUtils.cpp @@ -521,7 +521,9 @@ static std::vector readMembers(const object::Archive &Archive) { std::vector V; - for (const object::Archive::Child &C : Archive.children()) { + for (const auto &ChildOrErr : Archive.children()) { + error(ChildOrErr, "Archive::Child::getName failed"); + const object::Archive::Child C(*ChildOrErr); ErrorOr NameOrErr = C.getName(); error(NameOrErr, "Archive::Child::getName failed"); V.emplace_back(C, *NameOrErr); @@ -570,7 +572,7 @@ P += Sym.size() + 1; memcpy(P, DLLName.data(), DLLName.size()); - object::Archive::Child C(Parent, Buf); + object::Archive::Child C(Parent, Buf, nullptr); return NewArchiveIterator(C, DLLName); } Index: COFF/InputFiles.cpp =================================================================== --- COFF/InputFiles.cpp +++ COFF/InputFiles.cpp @@ -67,8 +67,11 @@ // Seen is a map from member files to boolean values. Initially // all members are mapped to false, which indicates all these files // are not read yet. - for (const Archive::Child &Child : File->children()) + for (auto &ChildOrErr : File->children()) { + error(ChildOrErr, "Failed to parse static library"); + const Archive::Child &Child = *ChildOrErr; Seen[Child.getChildOffset()].clear(); + } } // Returns a buffer pointing to a member file containing a given symbol. @@ -80,9 +83,9 @@ Archive::child_iterator It = *ItOrErr; // Return an empty buffer if we have already returned the same buffer. - if (Seen[It->getChildOffset()].test_and_set()) + if (Seen[(*It)->getChildOffset()].test_and_set()) return MemoryBufferRef(); - ErrorOr Ret = It->getMemoryBufferRef(); + ErrorOr Ret = (*It)->getMemoryBufferRef(); error(Ret, Twine("Could not get the buffer for the member defining symbol ") + Sym->getName()); return *Ret; Index: ELF/InputFiles.cpp =================================================================== --- ELF/InputFiles.cpp +++ ELF/InputFiles.cpp @@ -284,11 +284,14 @@ ErrorOr ItOrErr = Sym->getMember(); error(ItOrErr, "Could not get the member for symbol " + Sym->getName()); Archive::child_iterator It = *ItOrErr; + const ErrorOr &ChildOrErr = *It; + error(ChildOrErr, "Could not get the member for defining symbol " + + Sym->getName()); - if (!Seen.insert(It->getChildOffset()).second) + if (!Seen.insert((*It)->getChildOffset()).second) return MemoryBufferRef(); - ErrorOr Ret = It->getMemoryBufferRef(); + ErrorOr Ret = (*It)->getMemoryBufferRef(); error(Ret, "Could not get the buffer for the member defining symbol " + Sym->getName()); return *Ret; @@ -298,7 +301,10 @@ File = openArchive(MB); std::vector Result; - for (const Archive::Child &Child : File->children()) { + for (auto &ChildOrErr : File->children()) { + error(ChildOrErr, "Could not get the child of the archive " + + File->getFileName()); + const Archive::Child Child(*ChildOrErr); ErrorOr MbOrErr = Child.getMemoryBufferRef(); error(MbOrErr, "Could not get the buffer for a child of the archive " + File->getFileName()); Index: lib/ReaderWriter/FileArchive.cpp =================================================================== --- lib/ReaderWriter/FileArchive.cpp +++ lib/ReaderWriter/FileArchive.cpp @@ -49,9 +49,11 @@ if (member == _symbolMemberMap.end()) return nullptr; Archive::child_iterator ci = member->second; + if (ci->getError()) + return nullptr; // Don't return a member already returned - ErrorOr buf = ci->getBuffer(); + ErrorOr buf = (*ci)->getBuffer(); if (!buf) return nullptr; const char *memberStart = buf->data(); @@ -90,9 +92,11 @@ if (member == _symbolMemberMap.end()) return; Archive::child_iterator ci = member->second; + if (ci->getError()) + return; // Do nothing if a member is already instantiated. - ErrorOr buf = ci->getBuffer(); + ErrorOr buf = (*ci)->getBuffer(); if (!buf) return; const char *memberStart = buf->data(); @@ -168,9 +172,12 @@ private: std::error_code - instantiateMember(Archive::child_iterator member, + instantiateMember(Archive::child_iterator cOrErr, std::unique_ptr &result) const { - ErrorOr mbOrErr = member->getMemoryBufferRef(); + if (std::error_code ec = cOrErr->getError()) + return ec; + Archive::child_iterator member = cOrErr->get(); + ErrorOr mbOrErr = (*member)->getMemoryBufferRef(); if (std::error_code ec = mbOrErr.getError()) return ec; llvm::MemoryBufferRef mb = mbOrErr.get(); @@ -201,8 +208,11 @@ // Parses the given memory buffer as an object file, and returns true // code if the given symbol is a data symbol. If the symbol is not a data // symbol or does not exist, returns false. - bool isDataSymbol(Archive::child_iterator member, StringRef symbol) const { - ErrorOr buf = member->getMemoryBufferRef(); + bool isDataSymbol(Archive::child_iterator cOrErr, StringRef symbol) const { + if (cOrErr->getError()) + return false; + Archive::child_iterator member = cOrErr->get(); + ErrorOr buf = (*member)->getMemoryBufferRef(); if (buf.getError()) return false; std::unique_ptr mb(MemoryBuffer::getMemBuffer( @@ -244,7 +254,8 @@ Archive::child_iterator member = memberOrErr.get(); DEBUG_WITH_TYPE( "FileArchive", - llvm::dbgs() << llvm::format("0x%08llX ", member->getBuffer()->data()) + llvm::dbgs() << llvm::format("0x%08llX ", + (*member)->getBuffer()->data()) << "'" << name << "'\n"); _symbolMemberMap.insert(std::make_pair(name, member)); }