Index: llvm/trunk/include/llvm/Support/LockFileManager.h =================================================================== --- llvm/trunk/include/llvm/Support/LockFileManager.h +++ llvm/trunk/include/llvm/Support/LockFileManager.h @@ -88,7 +88,7 @@ std::string getErrorMessage() const; /// \brief Set error and error message - void setError(std::error_code &EC, StringRef ErrorMsg = "") { + void setError(const std::error_code &EC, StringRef ErrorMsg = "") { Error = EC; ErrorDiagMsg = ErrorMsg.str(); } Index: llvm/trunk/include/llvm/Support/raw_ostream.h =================================================================== --- llvm/trunk/include/llvm/Support/raw_ostream.h +++ llvm/trunk/include/llvm/Support/raw_ostream.h @@ -362,9 +362,7 @@ int FD; bool ShouldClose; - /// Error This flag is true if an error of any kind has been detected. - /// - bool Error; + std::error_code EC; uint64_t pos; @@ -383,7 +381,7 @@ size_t preferred_buffer_size() const override; /// Set the flag indicating that an output error has been encountered. - void error_detected() { Error = true; } + void error_detected(std::error_code EC) { this->EC = EC; } public: /// Open the specified file for writing. If an error occurs, information @@ -424,13 +422,13 @@ bool has_colors() const override; + std::error_code error() const { return EC; } + /// Return the value of the flag in this raw_fd_ostream indicating whether an /// output error has been encountered. /// This doesn't implicitly flush any pending output. Also, it doesn't /// guarantee to detect all errors unless the stream has been closed. - bool has_error() const { - return Error; - } + bool has_error() const { return bool(EC); } /// Set the flag read by has_error() to false. If the error flag is set at the /// time when this raw_ostream's destructor is called, report_fatal_error is @@ -441,9 +439,7 @@ /// Unless explicitly silenced." /// - from The Zen of Python, by Tim Peters /// - void clear_error() { - Error = false; - } + void clear_error() { EC = std::error_code(); } }; /// This returns a reference to a raw_ostream for standard output. Use it like: Index: llvm/trunk/lib/IR/Core.cpp =================================================================== --- llvm/trunk/lib/IR/Core.cpp +++ llvm/trunk/lib/IR/Core.cpp @@ -276,7 +276,8 @@ dest.close(); if (dest.has_error()) { - *ErrorMessage = strdup("Error printing to file"); + std::string E = "Error printing to file: " + dest.error().message(); + *ErrorMessage = strdup(E.c_str()); return true; } Index: llvm/trunk/lib/LTO/LTOCodeGenerator.cpp =================================================================== --- llvm/trunk/lib/LTO/LTOCodeGenerator.cpp +++ llvm/trunk/lib/LTO/LTOCodeGenerator.cpp @@ -218,7 +218,7 @@ ToolOutputFile Out(Path, EC, sys::fs::F_None); if (EC) { std::string ErrMsg = "could not open bitcode file for writing: "; - ErrMsg += Path; + ErrMsg += Path.str() + ": " + EC.message(); emitError(ErrMsg); return false; } @@ -229,7 +229,7 @@ if (Out.os().has_error()) { std::string ErrMsg = "could not write bitcode file: "; - ErrMsg += Path; + ErrMsg += Path.str() + ": " + Out.os().error().message(); emitError(ErrMsg); Out.os().clear_error(); return false; @@ -260,7 +260,9 @@ bool genResult = compileOptimized(&objFile.os()); objFile.os().close(); if (objFile.os().has_error()) { - emitError((Twine("could not write object file: ") + Filename).str()); + emitError((Twine("could not write object file: ") + Filename + ": " + + objFile.os().error().message()) + .str()); objFile.os().clear_error(); sys::fs::remove(Twine(Filename)); return false; Index: llvm/trunk/lib/Support/LockFileManager.cpp =================================================================== --- llvm/trunk/lib/Support/LockFileManager.cpp +++ llvm/trunk/lib/Support/LockFileManager.cpp @@ -201,12 +201,11 @@ Out.close(); if (Out.has_error()) { - // We failed to write out PID, so make up an excuse, remove the + // We failed to write out PID, so report the error, remove the // unique lock file, and fail. - auto EC = make_error_code(errc::no_space_on_device); std::string S("failed to write to "); S.append(UniqueLockFileName.str()); - setError(EC, S); + setError(Out.error(), S); sys::fs::remove(UniqueLockFileName); return; } Index: llvm/trunk/lib/Support/raw_ostream.cpp =================================================================== --- llvm/trunk/lib/Support/raw_ostream.cpp +++ llvm/trunk/lib/Support/raw_ostream.cpp @@ -517,8 +517,7 @@ /// FD is the file descriptor that this writes to. If ShouldClose is true, this /// closes the file when the stream is destroyed. raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered) - : raw_pwrite_stream(unbuffered), FD(fd), ShouldClose(shouldClose), - Error(false) { + : raw_pwrite_stream(unbuffered), FD(fd), ShouldClose(shouldClose) { if (FD < 0 ) { ShouldClose = false; return; @@ -552,8 +551,10 @@ raw_fd_ostream::~raw_fd_ostream() { if (FD >= 0) { flush(); - if (ShouldClose && sys::Process::SafelyCloseFileDescriptor(FD)) - error_detected(); + if (ShouldClose) { + if (auto EC = sys::Process::SafelyCloseFileDescriptor(FD)) + error_detected(EC); + } } #ifdef __MINGW32__ @@ -569,7 +570,8 @@ // has_error() and clear the error flag with clear_error() before // destructing raw_ostream objects which may have errors. if (has_error()) - report_fatal_error("IO failure on output stream.", /*GenCrashDiag=*/false); + report_fatal_error("IO failure on output stream: " + error().message(), + /*GenCrashDiag=*/false); } void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) { @@ -613,7 +615,7 @@ continue; // Otherwise it's a non-recoverable error. Note it and quit. - error_detected(); + error_detected(std::error_code(errno, std::generic_category())); break; } @@ -629,8 +631,8 @@ assert(ShouldClose); ShouldClose = false; flush(); - if (sys::Process::SafelyCloseFileDescriptor(FD)) - error_detected(); + if (auto EC = sys::Process::SafelyCloseFileDescriptor(FD)) + error_detected(EC); FD = -1; } @@ -645,7 +647,7 @@ pos = ::lseek(FD, off, SEEK_SET); #endif if (pos == (uint64_t)-1) - error_detected(); + error_detected(std::error_code(errno, std::generic_category())); return pos; }