This is an archive of the discontinued LLVM Phabricator instance.

error_code for dynamically generated error messages
ClosedPublic

Authored by kledzik on May 22 2014, 3:40 PM.

Details

Summary

This proposed patch adds a new kind of error_code, one which allows arbitrary
message strings.

error_code is based on the model that errors are enumerable and you may want
to programmatically handle when some function called fails with some specific
error_code.

lld uses ErrorOr<> extensively which is based on error_code. But the errors
that arise when parsing .o files or linking them are not usefully enumerable.
That is, there is nothing that can be programmatic done and you really want
an error message richer than “bad object format”. For instance, a richer
message might be “relocation 14 contains invalid relocation type (23)”.

This patch creates a subclass of error_category which dynamically associcates
a value and string. I hope this is not bending the error_code model too much.
If the idea is good, should this be pushed down from lld into llvm/Support?

As an example usage, I updated lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
to use make_dynamic_error_code().

Diff Detail

Event Timeline

kledzik updated this revision to Diff 9719.May 22 2014, 3:40 PM
kledzik retitled this revision from to error_code for dynamically generated error messages.
kledzik updated this object.
kledzik edited the test plan for this revision. (Show Details)
kledzik added a subscriber: Unknown Object (MLST).
ruiu edited edge metadata.May 22 2014, 3:45 PM

The idea looks good to me.

lib/Core/Error.cpp
182

What is this for?

190

Why don't you use std::mutex and std::lock_guard?

Bigcheese edited edge metadata.May 22 2014, 4:09 PM

One of the intents of ErrorOr was for this type of stuff to live there. This functionality was removed from ErrorOr because it was unused, but I would rather add it back to ErrorOr in some way than extend error_code like this.

I would also actually like to change ErrorOr to behave more like: https://github.com/boostcon/cppnow_presentations_2014/blob/master/files/expected.pdf?raw=true

The main part is to make the error type changeable and figure out a good default. Another feature that would make using ErrorOr easier is the monadic syntax with map.

Michael, I can see how ErrorOr<> could be improved. But should we block this on that improvement? Or is can we do this in lld in a way that is easy to update once ErrorOr<> is improved? For instance, use ErrorOr<void> for return types instead of error_code and have all dynamic error strings constructed though one utility function that can be rewritten later?

lib/Core/Error.cpp
182

The value of zero is reserved to mean "no error". The zeroth slot in the vector is lazily allocated.

190

No good reason. Why does llvm have is own Mutex if we now use C++11 that has std::mutex?

Bigcheese accepted this revision.May 22 2014, 4:44 PM
Bigcheese edited edge metadata.

I suppose this is fine for now as it's a rather simple change. We can just change make_dynamic_error_code in the future.

lib/Core/Error.cpp
190

Historical reasons. For example we should switch to std::error_code eventually.

This revision is now accepted and ready to land.May 22 2014, 4:44 PM
shankar.easwaran added inline comments.
lib/Core/Error.cpp
180

Nit pick spell error of success

189

How do we use the vector of messages ? Are these for predefined messages ? If so should it be a vector of StringRef ?

kledzik added inline comments.May 22 2014, 6:35 PM
lib/Core/Error.cpp
189

Each time make_dynamic_error_code() is called it copies the string to the vector which dynamically creates a new error code value. So rather that fixed error values and messages, we get dynamic error values and messages. Of course, this only makes sense if the clients never look at the value (other than testing against zero).

atanasyan accepted this revision.May 22 2014, 9:45 PM
atanasyan edited edge metadata.

LGTM

Will this work with the std::error_code once we switch?

As far as style goes I probably like the clang model best: pass an
DiagnosticsEngine down instead of passing the error back up. That way
we separate two concepts

  • an error we want to report to the user: foo.o in bar.a is corrupted.
  • an error condition we want to handle: open failed with no_such_file

in /usr/lib/libfoo.so. The caller will check the error_code and try
the next directory.

But I agree that this is isolated enough that it is fine if it also
works with std::error_code.

kledzik closed this revision.May 27 2014, 12:44 PM

Committed in r209681