bool isThinMember() const;
public:
- Child(const Archive *Parent, const char *Start);
+ Child(const Archive *Parent, const char *Start, std::error_code *EC);
Child(const Archive *Parent, StringRef Data, uint16_t StartOfFile);
bool operator ==(const Child &other) const {
}
const Archive *getParent() const { return Parent; }
- Child getNext() const;
+ ErrorOr<Child> getNext() const;
ErrorOr<StringRef> getName() const;
StringRef getRawName() const { return getHeader()->getName(); }
return getHeader()->getAccessMode();
}
/// \return the size of the archive member without the header or padding.
- uint64_t getSize() const;
+ ErrorOr<uint64_t> getSize() const;
/// \return the size in the archive header for this member.
- uint64_t getRawSize() const;
+ ErrorOr<uint64_t> getRawSize() const;
ErrorOr<StringRef> getBuffer() const;
uint64_t getChildOffset() const;
};
class child_iterator {
- Child child;
+ ErrorOr<Child> child;
public:
- child_iterator() : child(Child(nullptr, nullptr)) {}
+ child_iterator() : child(Child(nullptr, nullptr, nullptr)) {}
child_iterator(const Child &c) : child(c) {}
- const Child *operator->() const { return &child; }
- const Child &operator*() const { return child; }
+ child_iterator(std::error_code EC) : child(EC) {}
+ const ErrorOr<Child> *operator->() const { return &child; }
+ const ErrorOr<Child> &operator*() const { return child; }
bool operator==(const child_iterator &other) const {
- return child == other.child;
+ // We ignore error states so that comparisions with end() work, which
+ // allows range loops.
+ if (child.getError() || other.child.getError())
+ return false;
+ return *child == *other.child;
}
bool operator!=(const child_iterator &other) const {
return !(*this == other);
}
+ // Code in loops with child_iterators must check for errors on each loop
+ // iteration. And if there is an error break out of the loop.
child_iterator &operator++() { // Preincrement
- child = child.getNext();
+ assert(child && "Can't increment iterator with error");
+ child = child->getNext();
return *this;
}
};
typedef typename std::remove_reference<T>::type &reference;
typedef const typename std::remove_reference<T>::type &const_reference;
typedef typename std::remove_reference<T>::type *pointer;
+ typedef const typename std::remove_reference<T>::type *const_pointer;
public:
template <class E>
return toPointer(getStorage());
}
+ const_pointer operator->() const { return toPointer(getStorage()); }
+
reference operator *() {
return *getStorage();
}
+ const_reference operator*() const { return *getStorage(); }
+
private:
template <class OtherT>
void copyConstruct(const ErrorOr<OtherT> &Other) {
return Val;
}
+ const_pointer toPointer(const_pointer Val) const { return Val; }
+
pointer toPointer(wrap *Val) {
return &Val->get();
}
+ const_pointer toPointer(const wrap *Val) const { return &Val->get(); }
+
storage_type *getStorage() {
assert(!HasError && "Cannot get value when an error exists!");
return reinterpret_cast<storage_type*>(TStorage.buffer);
object::Archive *A = OB.getBinary();
// Look for our symbols in each Archive
object::Archive::child_iterator ChildIt = A->findSym(Name);
+ if (std::error_code EC = ChildIt->getError())
+ report_fatal_error(EC.message());
if (ChildIt != A->child_end()) {
// FIXME: Support nested archives?
ErrorOr<std::unique_ptr<object::Binary>> ChildBinOrErr =
- ChildIt->getAsBinary();
+ (*ChildIt)->getAsBinary();
if (ChildBinOrErr.getError())
continue;
std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();
object::Archive *A = OB.getBinary();
// Look for our symbols in each Archive
object::Archive::child_iterator ChildIt = A->findSym(Name);
+ if (std::error_code EC = ChildIt->getError())
+ report_fatal_error(EC.message());
if (ChildIt != A->child_end()) {
// FIXME: Support nested archives?
ErrorOr<std::unique_ptr<object::Binary>> ChildBinOrErr =
- ChildIt->getAsBinary();
+ (*ChildIt)->getAsBinary();
if (ChildBinOrErr.getError())
continue;
std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();
ErrorOr<uint32_t> ArchiveMemberHeader::getSize() const {
uint32_t Ret;
if (llvm::StringRef(Size, sizeof(Size)).rtrim(" ").getAsInteger(10, Ret))
- return object_error::parse_failed;
+ return object_error::parse_failed; // Size is not a decimal number.
return Ret;
}
uint16_t StartOfFile)
: Parent(Parent), Data(Data), StartOfFile(StartOfFile) {}
-Archive::Child::Child(const Archive *Parent, const char *Start)
+Archive::Child::Child(const Archive *Parent, const char *Start,
+ std::error_code *EC)
: Parent(Parent) {
if (!Start)
return;
uint64_t Size = sizeof(ArchiveMemberHeader);
Data = StringRef(Start, Size);
if (!isThinMember()) {
- Size += getRawSize();
+ ErrorOr<uint64_t> MemberSize = getRawSize();
+ if ((*EC = MemberSize.getError()))
+ return;
+ Size += MemberSize.get();
Data = StringRef(Start, Size);
}
}
}
-uint64_t Archive::Child::getSize() const {
+ErrorOr<uint64_t> Archive::Child::getSize() const {
if (Parent->IsThin) {
ErrorOr<uint32_t> Size = getHeader()->getSize();
- if (Size.getError())
- return 0;
+ if (std::error_code EC = Size.getError())
+ return EC;
return Size.get();
}
return Data.size() - StartOfFile;
}
-uint64_t Archive::Child::getRawSize() const {
+ErrorOr<uint64_t> Archive::Child::getRawSize() const {
ErrorOr<uint32_t> Size = getHeader()->getSize();
- if (Size.getError())
- return 0;
+ if (std::error_code EC = Size.getError())
+ return EC;
return Size.get();
}
}
ErrorOr<StringRef> Archive::Child::getBuffer() const {
- if (!isThinMember())
- return StringRef(Data.data() + StartOfFile, getSize());
+ if (!isThinMember()) {
+ ErrorOr<uint32_t> Size = getSize();
+ if (std::error_code EC = Size.getError())
+ return EC;
+ return StringRef(Data.data() + StartOfFile, Size.get());
+ }
ErrorOr<StringRef> Name = getName();
if (std::error_code EC = Name.getError())
return EC;
return Parent->ThinBuffers.back()->getBuffer();
}
-Archive::Child Archive::Child::getNext() const {
+ErrorOr<Archive::Child> Archive::Child::getNext() const {
size_t SpaceToSkip = Data.size();
// If it's odd, add 1 to make it even.
if (SpaceToSkip & 1)
const char *NextLoc = Data.data() + SpaceToSkip;
+ // Check to see if this is at the end of the archive.
+ if (NextLoc == Parent->Data.getBufferEnd())
+ return Child(Parent, nullptr, nullptr);
+
// Check to see if this is past the end of the archive.
- if (NextLoc >= Parent->Data.getBufferEnd())
- return Child(Parent, nullptr);
+ if (NextLoc > Parent->Data.getBufferEnd())
+ return object_error::parse_failed;
- return Child(Parent, NextLoc);
+ std::error_code EC;
+ Child Ret(Parent, NextLoc, &EC);
+ if (EC)
+ return EC;
+ return Ret;
}
uint64_t Archive::Child::getChildOffset() const {
}
// Get the special members.
- child_iterator i = child_begin(false);
- child_iterator e = child_end();
+ child_iterator I = child_begin(false);
+ if ((ec = I->getError()))
+ return;
+ child_iterator E = child_end();
- if (i == e) {
+ if (I == E) {
ec = std::error_code();
return;
}
+ const Child *C = &**I;
- StringRef Name = i->getRawName();
+ auto Increment = [&]() {
+ ++I;
+ if ((ec = I->getError()))
+ return true;
+ C = &**I;
+ return false;
+ };
+
+ StringRef Name = C->getRawName();
// Below is the pattern that is used to figure out the archive format
// GNU archive format
Format = K_BSD;
// We know that the symbol table is not an external file, so we just assert
// there is no error.
- SymbolTable = *i->getBuffer();
- ++i;
- setFirstRegular(*i);
+ SymbolTable = *C->getBuffer();
+ if (Increment())
+ return;
+ setFirstRegular(*C);
+
ec = std::error_code();
return;
}
if (Name.startswith("#1/")) {
Format = K_BSD;
// We know this is BSD, so getName will work since there is no string table.
- ErrorOr<StringRef> NameOrErr = i->getName();
+ ErrorOr<StringRef> NameOrErr = C->getName();
ec = NameOrErr.getError();
if (ec)
return;
if (Name == "__.SYMDEF SORTED" || Name == "__.SYMDEF") {
// We know that the symbol table is not an external file, so we just
// assert there is no error.
- SymbolTable = *i->getBuffer();
- ++i;
+ SymbolTable = *C->getBuffer();
+ if (Increment())
+ return;
}
- setFirstRegular(*i);
+ setFirstRegular(*C);
return;
}
if (Name == "/" || Name == "/SYM64/") {
// We know that the symbol table is not an external file, so we just assert
// there is no error.
- SymbolTable = *i->getBuffer();
+ SymbolTable = *C->getBuffer();
if (Name == "/SYM64/")
has64SymTable = true;
- ++i;
- if (i == e) {
+ if (Increment())
+ return;
+ if (I == E) {
ec = std::error_code();
return;
}
- Name = i->getRawName();
+ Name = C->getRawName();
}
if (Name == "//") {
Format = has64SymTable ? K_MIPS64 : K_GNU;
// The string table is never an external member, so we just assert on the
// ErrorOr.
- StringTable = *i->getBuffer();
- ++i;
- setFirstRegular(*i);
+ StringTable = *C->getBuffer();
+ if (Increment())
+ return;
+ setFirstRegular(*C);
ec = std::error_code();
return;
}
if (Name[0] != '/') {
Format = has64SymTable ? K_MIPS64 : K_GNU;
- setFirstRegular(*i);
+ setFirstRegular(*C);
ec = std::error_code();
return;
}
Format = K_COFF;
// We know that the symbol table is not an external file, so we just assert
// there is no error.
- SymbolTable = *i->getBuffer();
+ SymbolTable = *C->getBuffer();
+
+ if (Increment())
+ return;
- ++i;
- if (i == e) {
- setFirstRegular(*i);
+ if (I == E) {
+ setFirstRegular(*C);
ec = std::error_code();
return;
}
- Name = i->getRawName();
+ Name = C->getRawName();
if (Name == "//") {
// The string table is never an external member, so we just assert on the
// ErrorOr.
- StringTable = *i->getBuffer();
- ++i;
+ StringTable = *C->getBuffer();
+ if (Increment())
+ return;
}
- setFirstRegular(*i);
+ setFirstRegular(*C);
ec = std::error_code();
}
return Child(this, FirstRegularData, FirstRegularStartOfFile);
const char *Loc = Data.getBufferStart() + strlen(Magic);
- Child c(this, Loc);
- return c;
+ std::error_code EC;
+ Child c(this, Loc, &EC);
+ if (EC)
+ return child_iterator(EC);
+ return child_iterator(c);
}
Archive::child_iterator Archive::child_end() const {
- return Child(this, nullptr);
+ return Child(this, nullptr, nullptr);
}
StringRef Archive::Symbol::getName() const {
}
const char *Loc = Parent->getData().begin() + Offset;
- return Child(Parent, Loc);
+ std::error_code EC;
+ Child C(Parent, Loc, &EC);
+ if (EC)
+ return EC;
+ return C;
}
Archive::Symbol Archive::Symbol::getNext() const {
: IsNewMember(false), Name(Name), OldMember(OldMember) {}
NewArchiveIterator::NewArchiveIterator(StringRef FileName)
- : IsNewMember(true), Name(FileName), OldMember(nullptr, nullptr) {}
+ : IsNewMember(true), Name(FileName), OldMember(nullptr, nullptr, nullptr) {}
StringRef NewArchiveIterator::getName() const { return Name; }
Status.getSize());
} else {
const object::Archive::Child &OldMember = I.getOld();
+ ErrorOr<uint32_t> Size = OldMember.getSize();
+ if (std::error_code EC = Size.getError())
+ return std::make_pair("", EC);
printMemberHeader(Out, Kind, Thin, I.getName(), StringMapIndexIter,
- ModTime, UID, GID, Perms, OldMember.getSize());
+ ModTime, UID, GID, Perms, Size.get());
}
if (!Thin)
--- /dev/null
+!<arch>
+hello.c 1444941273 124 0 100644 10% `
+#include <stdio.h>
+#include <stdlib.h>
+int
+main()
+{
+ printf("Hello World\n");
+ return EXIT_SUCCESS;
+}
+foo.c 1444941645 124 0 100644 1% `
+void foo(void){}
+
--- /dev/null
+!<arch>
+hello.c 1444941273 124 0 100644 102 `
+#include <stdio.h>
+#include <stdlib.h>
+int
+main()
+{
+ printf("Hello World\n");
+ return EXIT_SUCCESS;
+}
+foo.c 1444941645 124 0 100644 1% `
+void foo(void){}
+
--- /dev/null
+!<arch>
+hello.c 1444941273 124 0 100644 102 `
+#include <stdio.h>
+#include <stdlib.h>
+int
+main()
+{
+ printf("Hello World\n");
+ return EXIT_SUCCESS;
+}
+foo.c 1444941645 124 0 100644 171 `
+void foo(void){}
+
+bar.c 1445026190 124 0 100644 17 `
+void foo(void){}
+
--- /dev/null
+// These test checks that llvm-objdump will not crash with malformed Archive
+// files. So the check line is not all that important but the bug fixes to
+// make sure llvm-objdump is robust is what matters.
+# RUN: llvm-objdump -macho -archive-headers \
+# RUN: %p/Inputs/libbogus1.a \
+# RUN: 2>&1 | FileCheck -check-prefix=bogus1 %s
+
+# bogus1: Invalid data was encountered while parsing the file
+
+# RUN: not llvm-objdump -macho -archive-headers \
+# RUN: %p/Inputs/libbogus2.a \
+# RUN: 2>&1 | FileCheck -check-prefix=bogus2 %s
+
+# bogus2: LLVM ERROR: Invalid data was encountered while parsing the file
+
+# RUN: not llvm-objdump -macho -archive-headers \
+# RUN: %p/Inputs/libbogus3.a \
+# RUN: 2>&1 | FileCheck -check-prefix=bogus3 %s
+
+# bogus3: LLVM ERROR: Invalid data was encountered while parsing the file
Buffers.reserve(CurrentArchives.size());
for (const auto &CurrentArchive : CurrentArchives) {
- for (const auto &Child : CurrentArchive->children()) {
+ for (auto ChildOrErr : CurrentArchive->children()) {
+ if (std::error_code Err = ChildOrErr.getError())
+ return Err;
+ const auto &Child = *ChildOrErr;
if (auto NameOrErr = Child.getName()) {
if (*NameOrErr == Filename) {
if (Timestamp != sys::TimeValue::PosixZeroTime() &&
printMode(Mode & 007);
outs() << ' ' << C.getUID();
outs() << '/' << C.getGID();
- outs() << ' ' << format("%6llu", C.getSize());
+ ErrorOr<uint64_t> Size = C.getSize();
+ failIfError(Size.getError());
+ outs() << ' ' << format("%6llu", Size.get());
outs() << ' ' << C.getLastModified().str();
outs() << ' ';
}
}
bool Filter = !Members.empty();
- for (const object::Archive::Child &C : OldArchive->children()) {
+ for (auto &ChildOrErr : OldArchive->children()) {
+ failIfError(ChildOrErr.getError());
+ const object::Archive::Child &C = *ChildOrErr;
+
ErrorOr<StringRef> NameOrErr = C.getName();
failIfError(NameOrErr.getError());
StringRef Name = NameOrErr.get();
int InsertPos = -1;
StringRef PosName = sys::path::filename(RelPos);
if (OldArchive) {
- for (auto &Child : OldArchive->children()) {
+ for (auto &ChildOrErr : OldArchive->children()) {
+ failIfError(ChildOrErr.getError());
+ auto &Child = ChildOrErr.get();
int Pos = Ret.size();
ErrorOr<StringRef> NameOrErr = Child.getName();
failIfError(NameOrErr.getError());
failIfError(LibOrErr.getError(), "Could not parse library");
Archives.push_back(std::move(*LibOrErr));
object::Archive &Lib = *Archives.back();
- for (auto &Member : Lib.children()) {
+ for (auto &MemberOrErr : Lib.children()) {
+ failIfError(MemberOrErr.getError());
+ auto &Member = MemberOrErr.get();
ErrorOr<StringRef> NameOrErr = Member.getName();
failIfError(NameOrErr.getError());
addMember(NewMembers, Member, *NameOrErr);
}
static void dumpArchive(const Archive *Arc) {
- for (const Archive::Child &ArcC : Arc->children()) {
+ for (auto &ErrorOrChild : Arc->children()) {
+ error(ErrorOrChild.getError());
+ const Archive::Child &ArcC = *ErrorOrChild;
ErrorOr<std::unique_ptr<Binary>> ChildOrErr = ArcC.getAsBinary();
if (std::error_code EC = ChildOrErr.getError()) {
// Ignore non-object files.
for (Archive::child_iterator I = A->child_begin(), E = A->child_end();
I != E; ++I) {
- ErrorOr<std::unique_ptr<Binary>> ChildOrErr = I->getAsBinary(&Context);
+ if (error(I->getError()))
+ return;
+ auto &C = I->get();
+ ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(&Context);
if (ChildOrErr.getError())
continue;
if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
for (Archive::child_iterator AI = A->child_begin(),
AE = A->child_end();
AI != AE; ++AI) {
+ if (error(AI->getError()))
+ return;
+ auto &C = AI->get();
ErrorOr<std::unique_ptr<Binary>> ChildOrErr =
- AI->getAsBinary(&Context);
+ C.getAsBinary(&Context);
if (ChildOrErr.getError())
continue;
if (SymbolicFile *O =
for (Archive::child_iterator AI = A->child_begin(),
AE = A->child_end();
AI != AE; ++AI) {
+ if (error(AI->getError()))
+ return;
+ auto &C = AI->get();
ErrorOr<std::unique_ptr<Binary>> ChildOrErr =
- AI->getAsBinary(&Context);
+ C.getAsBinary(&Context);
if (ChildOrErr.getError())
continue;
if (SymbolicFile *O =
std::unique_ptr<Archive> &A = *AOrErr;
for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end();
AI != AE; ++AI) {
- ErrorOr<std::unique_ptr<Binary>> ChildOrErr =
- AI->getAsBinary(&Context);
+ if (error(AI->getError()))
+ return;
+ auto &C = AI->get();
+ ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(&Context);
if (ChildOrErr.getError())
continue;
if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
outs() << format("%3d/", UID);
unsigned GID = C.getGID();
outs() << format("%-3d ", GID);
- uint64_t Size = C.getRawSize();
- outs() << format("%5" PRId64, Size) << " ";
+ ErrorOr<uint64_t> Size = C.getRawSize();
+ if (std::error_code EC = Size.getError())
+ report_fatal_error(EC.message());
+ outs() << format("%5" PRId64, Size.get()) << " ";
StringRef RawLastModified = C.getRawLastModified();
if (verbose) {
static void printArchiveHeaders(Archive *A, bool verbose, bool print_offset) {
for (Archive::child_iterator I = A->child_begin(false), E = A->child_end();
I != E; ++I) {
- Archive::Child C = *I;
+ if (std::error_code EC = I->getError())
+ report_fatal_error(EC.message());
+ const Archive::Child &C = **I;
printArchiveChild(C, verbose, print_offset);
}
}
printArchiveHeaders(A, !NonVerbose, ArchiveMemberOffsets);
for (Archive::child_iterator I = A->child_begin(), E = A->child_end();
I != E; ++I) {
- ErrorOr<std::unique_ptr<Binary>> ChildOrErr = I->getAsBinary();
+ if (std::error_code EC = I->getError()) {
+ errs() << "llvm-objdump: '" << Filename << "': " << EC.message()
+ << ".\n";
+ exit(1);
+ }
+ auto &C = I->get();
+ ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
if (ChildOrErr.getError())
continue;
if (MachOObjectFile *O = dyn_cast<MachOObjectFile>(&*ChildOrErr.get())) {
for (Archive::child_iterator AI = A->child_begin(),
AE = A->child_end();
AI != AE; ++AI) {
- ErrorOr<std::unique_ptr<Binary>> ChildOrErr = AI->getAsBinary();
+ if (std::error_code EC = AI->getError()) {
+ errs() << "llvm-objdump: '" << Filename
+ << "': " << EC.message() << ".\n";
+ exit(1);
+ }
+ auto &C = AI->get();
+ ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
if (ChildOrErr.getError())
continue;
if (MachOObjectFile *O =
for (Archive::child_iterator AI = A->child_begin(),
AE = A->child_end();
AI != AE; ++AI) {
- ErrorOr<std::unique_ptr<Binary>> ChildOrErr = AI->getAsBinary();
+ if (std::error_code EC = AI->getError()) {
+ errs() << "llvm-objdump: '" << Filename << "': " << EC.message()
+ << ".\n";
+ exit(1);
+ }
+ auto &C = AI->get();
+ ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
if (ChildOrErr.getError())
continue;
if (MachOObjectFile *O =
printArchiveHeaders(A.get(), !NonVerbose, ArchiveMemberOffsets);
for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end();
AI != AE; ++AI) {
- ErrorOr<std::unique_ptr<Binary>> ChildOrErr = AI->getAsBinary();
+ if (std::error_code EC = AI->getError()) {
+ errs() << "llvm-objdump: '" << Filename << "': " << EC.message()
+ << ".\n";
+ exit(1);
+ }
+ auto &C = AI->get();
+ ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
if (ChildOrErr.getError())
continue;
if (MachOObjectFile *O =
/// @brief Dump each object file in \a a;
static void DumpArchive(const Archive *a) {
- for (const Archive::Child &C : a->children()) {
+ for (auto &ErrorOrChild : a->children()) {
+ if (std::error_code EC = ErrorOrChild.getError())
+ report_error(a->getFileName(), EC);
+ const Archive::Child &C = *ErrorOrChild;
ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
if (std::error_code EC = ChildOrErr.getError())
if (EC != object_error::invalid_file_type)
/// @brief Dumps each object file in \a Arc;
static void dumpArchive(const Archive *Arc) {
- for (const auto &Child : Arc->children()) {
+ for (auto &ErrorOrChild : Arc->children()) {
+ if (std::error_code EC = ErrorOrChild.getError())
+ reportError(Arc->getFileName(), EC.message());
+ const auto &Child = *ErrorOrChild;
ErrorOr<std::unique_ptr<Binary>> ChildOrErr = Child.getAsBinary();
if (std::error_code EC = ChildOrErr.getError()) {
// Ignore non-object files.
for (object::Archive::child_iterator i = a->child_begin(),
e = a->child_end();
i != e; ++i) {
- ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary();
+ if (i->getError()) {
+ errs() << ToolName << ": " << file << ": " << i->getError().message()
+ << ".\n";
+ exit(1);
+ }
+ auto &c = i->get();
+ ErrorOr<std::unique_ptr<Binary>> ChildOrErr = c.getAsBinary();
if (std::error_code EC = ChildOrErr.getError()) {
errs() << ToolName << ": " << file << ": " << EC.message() << ".\n";
continue;
for (object::Archive::child_iterator i = UA->child_begin(),
e = UA->child_end();
i != e; ++i) {
- ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary();
+ if (std::error_code EC = i->getError()) {
+ errs() << ToolName << ": " << file << ": " << EC.message()
+ << ".\n";
+ exit(1);
+ }
+ auto &c = i->get();
+ ErrorOr<std::unique_ptr<Binary>> ChildOrErr = c.getAsBinary();
if (std::error_code EC = ChildOrErr.getError()) {
errs() << ToolName << ": " << file << ": " << EC.message()
<< ".\n";
for (object::Archive::child_iterator i = UA->child_begin(),
e = UA->child_end();
i != e; ++i) {
- ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary();
+ if (std::error_code EC = i->getError()) {
+ errs() << ToolName << ": " << file << ": " << EC.message()
+ << ".\n";
+ exit(1);
+ }
+ auto &c = i->get();
+ ErrorOr<std::unique_ptr<Binary>> ChildOrErr = c.getAsBinary();
if (std::error_code EC = ChildOrErr.getError()) {
errs() << ToolName << ": " << file << ": " << EC.message()
<< ".\n";
for (object::Archive::child_iterator i = UA->child_begin(),
e = UA->child_end();
i != e; ++i) {
- ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary();
+ if (std::error_code EC = i->getError()) {
+ errs() << ToolName << ": " << file << ": " << EC.message() << ".\n";
+ exit(1);
+ }
+ auto &c = i->get();
+ ErrorOr<std::unique_ptr<Binary>> ChildOrErr = c.getAsBinary();
if (std::error_code EC = ChildOrErr.getError()) {
errs() << ToolName << ": " << file << ": " << EC.message() << ".\n";
continue;