Index: lld/COFF/Writer.cpp =================================================================== --- lld/COFF/Writer.cpp +++ lld/COFF/Writer.cpp @@ -1519,9 +1519,10 @@ } void Writer::openFile(StringRef path) { - buffer = CHECK( - FileOutputBuffer::create(path, fileSize, FileOutputBuffer::F_executable), - "failed to open " + path); + if (Error E = FileOutputBuffer::create(path, fileSize, + FileOutputBuffer::F_executable) + .moveInto(buffer)) + fatal("failed to open " + llvm::toString(std::move(E))); } void Writer::createSEHTable() { Index: lld/ELF/Writer.cpp =================================================================== --- lld/ELF/Writer.cpp +++ lld/ELF/Writer.cpp @@ -2912,8 +2912,7 @@ FileOutputBuffer::create(config->outputFile, fileSize, flags); if (!bufferOrErr) { - error("failed to open " + config->outputFile + ": " + - llvm::toString(bufferOrErr.takeError())); + error("failed to open " + llvm::toString(bufferOrErr.takeError())); return; } buffer = std::move(*bufferOrErr); Index: lld/MachO/Writer.cpp =================================================================== --- lld/MachO/Writer.cpp +++ lld/MachO/Writer.cpp @@ -1073,8 +1073,7 @@ FileOutputBuffer::F_executable); if (!bufferOrErr) - error("failed to open " + config->outputFile + ": " + - llvm::toString(bufferOrErr.takeError())); + error("failed to open " + llvm::toString(bufferOrErr.takeError())); else buffer = std::move(*bufferOrErr); } Index: lld/wasm/Writer.cpp =================================================================== --- lld/wasm/Writer.cpp +++ lld/wasm/Writer.cpp @@ -1641,8 +1641,7 @@ FileOutputBuffer::F_executable); if (!bufferOrErr) - error("failed to open " + config->outputFile + ": " + - toString(bufferOrErr.takeError())); + error("failed to open " + toString(bufferOrErr.takeError())); else buffer = std::move(*bufferOrErr); } Index: llvm/include/llvm/Support/FileOutputBuffer.h =================================================================== --- llvm/include/llvm/Support/FileOutputBuffer.h +++ llvm/include/llvm/Support/FileOutputBuffer.h @@ -45,6 +45,8 @@ /// Otherwise, the file shrinks or grows as necessary based on the value of /// \p Size. It is an error to specify F_modify and Size=-1 if \p FilePath /// does not exist. + /// + /// Returns a \a FileError pointing at \p FilePath on failure. static Expected> create(StringRef FilePath, size_t Size, unsigned Flags = 0); @@ -65,6 +67,8 @@ /// is called, the file is deleted in the destructor. The optional parameter /// is used if it turns out you want the file size to be smaller than /// initially requested. + /// + /// Returns a \a FileError pointing at \a getPath() on failure. virtual Error commit() = 0; /// If this object was previously committed, the destructor just deletes Index: llvm/lib/InterfaceStub/ELFObjHandler.cpp =================================================================== --- llvm/lib/InterfaceStub/ELFObjHandler.cpp +++ llvm/lib/InterfaceStub/ELFObjHandler.cpp @@ -618,9 +618,8 @@ FileOutputBuffer::create(FilePath, Builder.getSize()); if (!BufOrError) return createStringError(errc::invalid_argument, - toString(BufOrError.takeError()) + - " when trying to open `" + FilePath + - "` for writing"); + "failed to open " + + toString(BufOrError.takeError())); // Write binary to file. std::unique_ptr FileBuf = std::move(*BufOrError); Index: llvm/lib/Support/FileOutputBuffer.cpp =================================================================== --- llvm/lib/Support/FileOutputBuffer.cpp +++ llvm/lib/Support/FileOutputBuffer.cpp @@ -49,7 +49,7 @@ Buffer.unmap(); // Atomically replace the existing file with the new one. - return Temp.keep(FinalPath); + return createFileError(FinalPath, Temp.keep(FinalPath)); } ~OnDiskBuffer() override { @@ -99,7 +99,7 @@ std::error_code EC; if (auto EC = openFileForWrite(FinalPath, FD, CD_CreateAlways, OF_None, Mode)) - return errorCodeToError(EC); + return createFileError(FinalPath, EC); raw_fd_ostream OS(FD, /*shouldClose=*/true, /*unbuffered=*/true); OS << StringRef((const char *)Buffer.base(), BufferSize); return Error::success(); @@ -119,7 +119,7 @@ MemoryBlock MB = Memory::allocateMappedMemory( Size, nullptr, sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC); if (EC) - return errorCodeToError(EC); + return createFileError(Path, EC); return std::make_unique(Path, MB, Size, Mode); } @@ -128,12 +128,12 @@ Expected FileOrErr = fs::TempFile::create(Path + ".tmp%%%%%%%", Mode); if (!FileOrErr) - return FileOrErr.takeError(); + return createFileError(Path, FileOrErr.takeError()); fs::TempFile File = std::move(*FileOrErr); if (auto EC = fs::resize_file_before_mapping_readwrite(File.FD, Size)) { consumeError(File.discard()); - return errorCodeToError(EC); + return createFileError(Path, EC); } // Mmap it. @@ -181,7 +181,7 @@ // destination file and write to it on commit(). switch (Stat.type()) { case fs::file_type::directory_file: - return errorCodeToError(errc::is_a_directory); + return createFileError(Path, errc::is_a_directory); case fs::file_type::regular_file: case fs::file_type::file_not_found: case fs::file_type::status_error: Index: llvm/tools/llvm-cvtres/llvm-cvtres.cpp =================================================================== --- llvm/tools/llvm-cvtres/llvm-cvtres.cpp +++ llvm/tools/llvm-cvtres/llvm-cvtres.cpp @@ -72,10 +72,6 @@ exit(1); } -static void reportError(StringRef Input, std::error_code EC) { - reportError(Twine(Input) + ": " + EC.message() + ".\n"); -} - static void error(StringRef Input, Error EC) { if (!EC) return; @@ -210,11 +206,8 @@ std::unique_ptr OutputBuffer = error(llvm::object::writeWindowsResourceCOFF(MachineType, Parser, DateTimeStamp)); - auto FileOrErr = - FileOutputBuffer::create(OutputFile, OutputBuffer->getBufferSize()); - if (!FileOrErr) - reportError(OutputFile, errorToErrorCode(FileOrErr.takeError())); - std::unique_ptr FileBuffer = std::move(*FileOrErr); + std::unique_ptr FileBuffer = error( + FileOutputBuffer::create(OutputFile, OutputBuffer->getBufferSize())); std::copy(OutputBuffer->getBufferStart(), OutputBuffer->getBufferEnd(), FileBuffer->getBufferStart()); error(FileBuffer->commit()); Index: llvm/tools/llvm-lipo/llvm-lipo.cpp =================================================================== --- llvm/tools/llvm-lipo/llvm-lipo.cpp +++ llvm/tools/llvm-lipo/llvm-lipo.cpp @@ -504,7 +504,7 @@ ? FileOutputBuffer::F_executable : 0); if (!OutFileOrError) - reportError(OutputFileName, OutFileOrError.takeError()); + reportError(OutFileOrError.takeError()); std::copy(B->getMemoryBufferRef().getBufferStart(), B->getMemoryBufferRef().getBufferEnd(), OutFileOrError.get()->getBufferStart()); Index: llvm/tools/llvm-mt/llvm-mt.cpp =================================================================== --- llvm/tools/llvm-mt/llvm-mt.cpp +++ llvm/tools/llvm-mt/llvm-mt.cpp @@ -143,8 +143,7 @@ reportError("empty manifest not written"); Expected> FileOrErr = FileOutputBuffer::create(OutputFile, OutputBuffer->getBufferSize()); - if (!FileOrErr) - reportError(OutputFile, errorToErrorCode(FileOrErr.takeError())); + error(FileOrErr.takeError()); std::unique_ptr FileBuffer = std::move(*FileOrErr); std::copy(OutputBuffer->getBufferStart(), OutputBuffer->getBufferEnd(), FileBuffer->getBufferStart()); Index: llvm/unittests/Support/FileOutputBufferTest.cpp =================================================================== --- llvm/unittests/Support/FileOutputBufferTest.cpp +++ llvm/unittests/Support/FileOutputBufferTest.cpp @@ -13,6 +13,8 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Testing/Support/Error.h" +#include "llvm/Testing/Support/SupportHelpers.h" #include "gtest/gtest.h" using namespace llvm;