Previously, we would emit error messages like "IO failure on output
stream". This change causes use to include information about what
actually went wrong, e.g. "No space left on device".
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
As an alternative, I considered using an Error instead of an error_code. I decided against that, because
- It produces a riskier change. Error.h depends on raw_ostream.h, and now we would also have an edge going the other way. Working around this is possible, but can affect clients that depend on Error.h, of which there are many.
- It changes the semantics from unchecked errors resulting in fatals to unchecked errors *or successes* resulting in fatals. This could be worked around, but it would make the change larger comparing to just using a type that already provides compatible semantics.
- raw_ostream et al. are meant to look like standard C++ types. std::error_code is arguably a better fit for that than llvm::Error.
- The code that raw_fd_ostream calls already produces error_codes, so by just using those, we avoid having to convert them to Error.
In short, std::error_code makes for a simpler, less risky change that fits with the existing code and semantics, so I chose to go with that.
Separately, we should cut this edge if possible. Widely included headers like Error.h should have as few transitive includes as possible.
- It changes the semantics from unchecked errors resulting in fatals to unchecked errors *or successes* resulting in fatals. This could be worked around, but it would make the change larger comparing to just using a type that already provides compatible semantics.
- raw_ostream et al. are meant to look like standard C++ types. std::error_code is arguably a better fit for that than llvm::Error.
- The code that raw_fd_ostream calls already produces error_codes, so by just using those, we avoid having to convert them to Error.
In short, std::error_code makes for a simpler, less risky change that fits with the existing code and semantics, so I chose to go with that.
I totally agree. :)
Looks good!
llvm/lib/LTO/LTOCodeGenerator.cpp | ||
---|---|---|
263 ↗ | (On Diff #119924) | Separately, emitError and emitWarning should really take something other than std::string. |
Oh, do you think this is worth a unit test? It should be easy to add one for "file not found" or something, if you try creating a file in a directory that doesn't exist.
Oh, do you think this is worth a unit test? It should be easy to add one for "file not found" or something, if you try creating a file in a directory that doesn't exist.
I would like to have a test for this, but after trying a few things for a couple of hours I decided to punt on that and try to ship the improvement without adding a test. The issue is that this change only applies to errors that happen after the file has been opened (errors during open were already reported back to the caller). That makes it harder to come up with a test that works reliably across operating systems. I tried opening the file and getting an fd, then passing the fd to the raw_fd_ostream constructor that takes one, closing the fd, then writing to the stream - but the result is that the test dies before ever reporting success or failure (on Windows). There are other things we could do, for example mocking the calls that actually interact with the filesystem, but that didn't really seem worth the effort. If you agree, I'd like to ship this without the test for now.