This is an archive of the discontinued LLVM Phabricator instance.

This removes the eating of the error in Archive::Child::getSize() when the characters in the size field in the archive header for the member is not a number.
ClosedPublic

Authored by enderby on Oct 22 2015, 11:51 AM.

Details

Summary

To do this we have all of the needed methods return ErrorOr to push them up until we get out of lib.
Then the tools and can handle the error in whatever way is appropriate for that tool.

So the solution is to plumb all the ErrorOr stuff through everything that touches archives.
This include its iterators as one can create an Archive object but the first or any other
Child object may fail to be created due to a bad size field in its header.

Thanks to Lang Hames on the changes making child_iterator contain an
ErrorOr<Child> instead of a Child and the needed changes to ErrorOr.h to add
operator overloading for * and -> .

We don’t want to use llvm_unreachable() as it calls abort() and is produces a “crash”
and using report_fatal_error() to move the error checking will cause the program to
stop, neither of which are really correct in library code. There are still some uses of
these that should be cleaned up in this library code for other than the size field.

Also corrected the code where the size gets us to the “at the end of the archive”
which is OK but past the end of the archive will return object_error::parse_failed now.

The test cases use archives with text files so one can see the non-digit character,
in this case a ‘%’, in the size field.

These changes will require corresponding changes to the lld project. That patch will be posted next.
And that will be committed immediately after this change when committed. But this revision will cause lld failures with this alone which is expected.

Diff Detail

Event Timeline

enderby updated this revision to Diff 38151.Oct 22 2015, 11:51 AM
enderby retitled this revision from to This removes the eating of the error in Archive::Child::getSize() when the characters in the size field in the archive header for the member is not a number..
enderby updated this object.
enderby added reviewers: rafael, ruiu.
enderby added subscribers: llvm-commits, lhames.
rafael added inline comments.Oct 24 2015, 6:10 AM
lib/Object/Archive.cpp
99

You can write this as

if ((EC = MemberSize.getError())

return;
175–179

This introduces a memory allocation. Please don't do that. In fact, please don't add Child::create at all. We don't want to allocate a Child, they are passed by value. This should be

std::error_code EC;
Child Ret(Parent, NextLoc, EC);
if (EC)

return EC;

return Ret;

enderby updated this revision to Diff 38451.Oct 26 2015, 12:50 PM

Addressed Rafael's comments with the updated diff.

enderby updated this revision to Diff 38452.Oct 26 2015, 12:58 PM

Sorry my tree was a bit out of date and was showing diffs in tools/llvm-objdump/MachODump.cpp that were in r251215 that Rafael did to Simplify boolean expressions in tools/llvm-objdump. Sorry about that.

rafael edited edge metadata.Oct 27 2015, 8:09 AM
rafael added a subscriber: rafael.

I applied the patch and I am currently reviewing it.

Two quick things I noticed:

  • The formatting is odd, please git-clang-format the patch.
  • Adding the malformed-archives directory seems premature, just put

the .a in Inputs.

rafael added inline comments.Oct 27 2015, 9:30 AM
include/llvm/Object/Archive.h
108

I don't think the iterator should include the possibility of being at error. Everywhere else we just push the error outwards.

This should still be just "Child child;" and then when appropriate we should use a ErrorOr<child_iterator>. For example, child_begin should return that.

lib/Object/Archive.cpp
185

This changes are nice but independent. Please leave them for another path.

I implemented some, but not all, the suggestions while reviewing the
patch. It should make it easier to finish it up.

lhames added inline comments.Oct 27 2015, 4:18 PM
include/llvm/Object/Archive.h
108

Unfortunately we can't just wrap the iterator here: Increment itself can fail if any given Child's header is damaged, so the iterator needs to handle the possibility of failure.

As a bonus, handling failure inside the iterator allows you to use ranged-based for loops, which you can't use if the iterator is wrapped.

I agree with Lang and like the original patch where were were handling failure was done inside the iterator. It does allow use of ranged-based for loops and appears to me much cleaner in the code especially in the lld changes needed in http://reviews.llvm.org/D13990 .

Rafael, I did "finish it up" based on your t.diff patch and that is below and includes the re-formatting with clang-format-diff, removal of the malformed-archives directory putting the .a files in Inputs and removal of the "nice but independent" changes.

And here are the "finished up" corresponding changes that would be needed for lld:

enderby updated this revision to Diff 39388.Nov 5 2015, 11:20 AM
enderby edited edge metadata.

This final patch includes many suggested updates from Rafael Espindola emails. Rafael's last email contained:

On Nov 5, 2015, at 6:48 AM, Rafael Espíndola <rafael.espindola@gmail.com> wrote:

LGTM with the "exit with 0 on error" issues fixed.

enderby accepted this revision.Nov 5 2015, 11:29 AM
enderby added a reviewer: enderby.

Closed with commit r252192.

This revision is now accepted and ready to land.Nov 5 2015, 11:29 AM