diff options
Diffstat (limited to 'llvm/tools')
-rw-r--r-- | llvm/tools/gold/gold-plugin.cpp | 9 | ||||
-rw-r--r-- | llvm/tools/lli/lli.cpp | 18 | ||||
-rw-r--r-- | llvm/tools/llvm-ar/llvm-ar.cpp | 15 | ||||
-rw-r--r-- | llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp | 9 | ||||
-rw-r--r-- | llvm/tools/llvm-cov/llvm-cov.cpp | 20 | ||||
-rw-r--r-- | llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp | 9 | ||||
-rw-r--r-- | llvm/tools/llvm-mc/llvm-mc.cpp | 10 | ||||
-rw-r--r-- | llvm/tools/llvm-mcmarkup/llvm-mcmarkup.cpp | 9 | ||||
-rw-r--r-- | llvm/tools/llvm-nm/llvm-nm.cpp | 6 | ||||
-rw-r--r-- | llvm/tools/llvm-objdump/MachODump.cpp | 19 | ||||
-rw-r--r-- | llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp | 47 | ||||
-rw-r--r-- | llvm/tools/llvm-symbolizer/LLVMSymbolize.cpp | 7 | ||||
-rw-r--r-- | llvm/tools/lto/lto.cpp | 6 | ||||
-rw-r--r-- | llvm/tools/yaml2obj/yaml2obj.cpp | 7 |
14 files changed, 104 insertions, 87 deletions
diff --git a/llvm/tools/gold/gold-plugin.cpp b/llvm/tools/gold/gold-plugin.cpp index 6d52f62b210..f424e46eb46 100644 --- a/llvm/tools/gold/gold-plugin.cpp +++ b/llvm/tools/gold/gold-plugin.cpp @@ -280,11 +280,14 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, if (file->offset) { offset = file->offset; } - if (std::error_code ec = MemoryBuffer::getOpenFileSlice( - file->fd, file->name, buffer, file->filesize, offset)) { - (*message)(LDPL_ERROR, ec.message().c_str()); + ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = + MemoryBuffer::getOpenFileSlice(file->fd, file->name, file->filesize, + offset); + if (std::error_code EC = BufferOrErr.getError()) { + (*message)(LDPL_ERROR, EC.message().c_str()); return LDPS_ERR; } + buffer = std::move(BufferOrErr.get()); view = buffer->getBufferStart(); } diff --git a/llvm/tools/lli/lli.cpp b/llvm/tools/lli/lli.cpp index f69fb435c68..48828c1d68a 100644 --- a/llvm/tools/lli/lli.cpp +++ b/llvm/tools/lli/lli.cpp @@ -285,8 +285,8 @@ public: if (!getCacheFilename(ModuleID, CacheName)) return nullptr; // Load the object from the cache filename - std::unique_ptr<MemoryBuffer> IRObjectBuffer; - MemoryBuffer::getFile(CacheName.c_str(), IRObjectBuffer, -1, false); + ErrorOr<std::unique_ptr<MemoryBuffer>> IRObjectBuffer = + MemoryBuffer::getFile(CacheName.c_str(), -1, false); // If the file isn't there, that's OK. if (!IRObjectBuffer) return nullptr; @@ -294,7 +294,7 @@ public: // because the file has probably just been mmapped. Instead we make // a copy. The filed-based buffer will be released when it goes // out of scope. - return MemoryBuffer::getMemBufferCopy(IRObjectBuffer->getBuffer()); + return MemoryBuffer::getMemBufferCopy(IRObjectBuffer.get()->getBuffer()); } private: @@ -538,15 +538,15 @@ int main(int argc, char **argv, char * const *envp) { } for (unsigned i = 0, e = ExtraArchives.size(); i != e; ++i) { - std::unique_ptr<MemoryBuffer> ArBuf; - std::error_code ec; - ec = MemoryBuffer::getFileOrSTDIN(ExtraArchives[i], ArBuf); - if (ec) { + ErrorOr<std::unique_ptr<MemoryBuffer>> ArBuf = + MemoryBuffer::getFileOrSTDIN(ExtraArchives[i]); + if (!ArBuf) { Err.print(argv[0], errs()); return 1; } - object::Archive *Ar = new object::Archive(std::move(ArBuf), ec); - if (ec || !Ar) { + std::error_code EC; + object::Archive *Ar = new object::Archive(std::move(ArBuf.get()), EC); + if (EC || !Ar) { Err.print(argv[0], errs()); return 1; } diff --git a/llvm/tools/llvm-ar/llvm-ar.cpp b/llvm/tools/llvm-ar/llvm-ar.cpp index 4bd586be451..f638e55c5c7 100644 --- a/llvm/tools/llvm-ar/llvm-ar.cpp +++ b/llvm/tools/llvm-ar/llvm-ar.cpp @@ -770,10 +770,10 @@ static void performWriteOperation(ArchiveOperation Operation, const char *Filename = Member.getNew(); int FD = Member.getFD(); const sys::fs::file_status &Status = Member.getStatus(); - failIfError(MemoryBuffer::getOpenFile(FD, Filename, MemberBuffer, - Status.getSize(), false), - Filename); - + ErrorOr<std::unique_ptr<MemoryBuffer>> MemberBufferOrErr = + MemoryBuffer::getOpenFile(FD, Filename, Status.getSize(), false); + failIfError(MemberBufferOrErr.getError(), Filename); + MemberBuffer = std::move(MemberBufferOrErr.get()); } else { object::Archive::child_iterator OldMember = Member.getOld(); ErrorOr<std::unique_ptr<MemoryBuffer>> MemberBufferOrErr = @@ -934,8 +934,9 @@ int ar_main(char **argv) { static int performOperation(ArchiveOperation Operation) { // Create or open the archive object. - std::unique_ptr<MemoryBuffer> Buf; - std::error_code EC = MemoryBuffer::getFile(ArchiveName, Buf, -1, false); + ErrorOr<std::unique_ptr<MemoryBuffer>> Buf = + MemoryBuffer::getFile(ArchiveName, -1, false); + std::error_code EC = Buf.getError(); if (EC && EC != errc::no_such_file_or_directory) { errs() << ToolName << ": error opening '" << ArchiveName << "': " << EC.message() << "!\n"; @@ -943,7 +944,7 @@ static int performOperation(ArchiveOperation Operation) { } if (!EC) { - object::Archive Archive(std::move(Buf), EC); + object::Archive Archive(std::move(Buf.get()), EC); if (EC) { errs() << ToolName << ": error loading '" << ArchiveName diff --git a/llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp b/llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp index fe2b235e53c..15567cf3123 100644 --- a/llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp +++ b/llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp @@ -478,10 +478,11 @@ static void PrintSize(uint64_t Bits) { /// AnalyzeBitcode - Analyze the bitcode file specified by InputFilename. static int AnalyzeBitcode() { // Read the input file. - std::unique_ptr<MemoryBuffer> MemBuf; - - if (std::error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, MemBuf)) - return Error("Error reading '" + InputFilename + "': " + ec.message()); + ErrorOr<std::unique_ptr<MemoryBuffer>> MemBufOrErr = + MemoryBuffer::getFileOrSTDIN(InputFilename); + if (std::error_code EC = MemBufOrErr.getError()) + return Error("Error reading '" + InputFilename + "': " + EC.message()); + std::unique_ptr<MemoryBuffer> MemBuf = std::move(MemBufOrErr.get()); if (MemBuf->getBufferSize() & 3) return Error("Bitcode stream should be a multiple of 4 bytes in length"); diff --git a/llvm/tools/llvm-cov/llvm-cov.cpp b/llvm/tools/llvm-cov/llvm-cov.cpp index 04de4431059..18cc1b110e2 100644 --- a/llvm/tools/llvm-cov/llvm-cov.cpp +++ b/llvm/tools/llvm-cov/llvm-cov.cpp @@ -97,27 +97,29 @@ void reportCoverage(StringRef SourceFile) { : InputGCDA; GCOVFile GF; - std::unique_ptr<MemoryBuffer> GCNO_Buff; - if (std::error_code ec = MemoryBuffer::getFileOrSTDIN(GCNO, GCNO_Buff)) { - errs() << GCNO << ": " << ec.message() << "\n"; + ErrorOr<std::unique_ptr<MemoryBuffer>> GCNO_Buff = + MemoryBuffer::getFileOrSTDIN(GCNO); + if (std::error_code EC = GCNO_Buff.getError()) { + errs() << GCNO << ": " << EC.message() << "\n"; return; } - GCOVBuffer GCNO_GB(GCNO_Buff.get()); + GCOVBuffer GCNO_GB(GCNO_Buff.get().get()); if (!GF.readGCNO(GCNO_GB)) { errs() << "Invalid .gcno File!\n"; return; } - std::unique_ptr<MemoryBuffer> GCDA_Buff; - if (std::error_code ec = MemoryBuffer::getFileOrSTDIN(GCDA, GCDA_Buff)) { - if (ec != errc::no_such_file_or_directory) { - errs() << GCDA << ": " << ec.message() << "\n"; + ErrorOr<std::unique_ptr<MemoryBuffer>> GCDA_Buff = + MemoryBuffer::getFileOrSTDIN(GCDA); + if (std::error_code EC = GCDA_Buff.getError()) { + if (EC != errc::no_such_file_or_directory) { + errs() << GCDA << ": " << EC.message() << "\n"; return; } // Clear the filename to make it clear we didn't read anything. GCDA = "-"; } else { - GCOVBuffer GCDA_GB(GCDA_Buff.get()); + GCOVBuffer GCDA_GB(GCDA_Buff.get().get()); if (!GF.readGCDA(GCDA_GB)) { errs() << "Invalid .gcda File!\n"; return; diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp index 0eb6e4f4304..f44b0e3ef5e 100644 --- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -66,14 +66,15 @@ DumpType("debug-dump", cl::init(DIDT_All), clEnumValEnd)); static void DumpInput(const StringRef &Filename) { - std::unique_ptr<MemoryBuffer> Buff; + ErrorOr<std::unique_ptr<MemoryBuffer>> Buff = + MemoryBuffer::getFileOrSTDIN(Filename); - if (std::error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) { - errs() << Filename << ": " << ec.message() << "\n"; + if (std::error_code EC = Buff.getError()) { + errs() << Filename << ": " << EC.message() << "\n"; return; } - ErrorOr<ObjectFile *> ObjOrErr(ObjectFile::createObjectFile(Buff)); + ErrorOr<ObjectFile *> ObjOrErr(ObjectFile::createObjectFile(Buff.get())); if (std::error_code EC = ObjOrErr.getError()) { errs() << Filename << ": " << EC.message() << '\n'; return; diff --git a/llvm/tools/llvm-mc/llvm-mc.cpp b/llvm/tools/llvm-mc/llvm-mc.cpp index 72294caef3b..4c5b230573b 100644 --- a/llvm/tools/llvm-mc/llvm-mc.cpp +++ b/llvm/tools/llvm-mc/llvm-mc.cpp @@ -367,13 +367,13 @@ int main(int argc, char **argv) { if (!TheTarget) return 1; - std::unique_ptr<MemoryBuffer> BufferPtr; - if (std::error_code ec = - MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr)) { - errs() << ProgName << ": " << ec.message() << '\n'; + ErrorOr<std::unique_ptr<MemoryBuffer>> BufferPtr = + MemoryBuffer::getFileOrSTDIN(InputFilename); + if (std::error_code EC = BufferPtr.getError()) { + errs() << ProgName << ": " << EC.message() << '\n'; return 1; } - MemoryBuffer *Buffer = BufferPtr.release(); + MemoryBuffer *Buffer = BufferPtr->release(); SourceMgr SrcMgr; diff --git a/llvm/tools/llvm-mcmarkup/llvm-mcmarkup.cpp b/llvm/tools/llvm-mcmarkup/llvm-mcmarkup.cpp index cbb0d51dd3d..a878f1157d5 100644 --- a/llvm/tools/llvm-mcmarkup/llvm-mcmarkup.cpp +++ b/llvm/tools/llvm-mcmarkup/llvm-mcmarkup.cpp @@ -135,12 +135,13 @@ MarkupTag MarkupParser::parseTag() { } static void parseMCMarkup(StringRef Filename) { - std::unique_ptr<MemoryBuffer> BufferPtr; - if (std::error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, BufferPtr)) { - errs() << ToolName << ": " << ec.message() << '\n'; + ErrorOr<std::unique_ptr<MemoryBuffer>> BufferPtr = + MemoryBuffer::getFileOrSTDIN(Filename); + if (std::error_code EC = BufferPtr.getError()) { + errs() << ToolName << ": " << EC.message() << '\n'; return; } - MemoryBuffer *Buffer = BufferPtr.release(); + MemoryBuffer *Buffer = BufferPtr->release(); SourceMgr SrcMgr; diff --git a/llvm/tools/llvm-nm/llvm-nm.cpp b/llvm/tools/llvm-nm/llvm-nm.cpp index d3918547d84..8a89dd80dba 100644 --- a/llvm/tools/llvm-nm/llvm-nm.cpp +++ b/llvm/tools/llvm-nm/llvm-nm.cpp @@ -805,9 +805,11 @@ static bool checkMachOAndArchFlags(SymbolicFile *O, std::string &Filename) { } static void dumpSymbolNamesFromFile(std::string &Filename) { - std::unique_ptr<MemoryBuffer> Buffer; - if (error(MemoryBuffer::getFileOrSTDIN(Filename, Buffer), Filename)) + ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = + MemoryBuffer::getFileOrSTDIN(Filename); + if (error(BufferOrErr.getError(), Filename)) return; + std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get()); LLVMContext &Context = getGlobalContext(); ErrorOr<Binary *> BinaryOrErr = createBinary(Buffer, &Context); diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp index 74fdfef67ce..4b46ac4fc0b 100644 --- a/llvm/tools/llvm-objdump/MachODump.cpp +++ b/llvm/tools/llvm-objdump/MachODump.cpp @@ -195,15 +195,15 @@ static void DisassembleInputMachO2(StringRef Filename, MachOObjectFile *MachOOF); void llvm::DisassembleInputMachO(StringRef Filename) { - std::unique_ptr<MemoryBuffer> Buff; - - if (std::error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) { - errs() << "llvm-objdump: " << Filename << ": " << ec.message() << "\n"; + ErrorOr<std::unique_ptr<MemoryBuffer>> Buff = + MemoryBuffer::getFileOrSTDIN(Filename); + if (std::error_code EC = Buff.getError()) { + errs() << "llvm-objdump: " << Filename << ": " << EC.message() << "\n"; return; } std::unique_ptr<MachOObjectFile> MachOOF(static_cast<MachOObjectFile *>( - ObjectFile::createMachOObjectFile(Buff).get())); + ObjectFile::createMachOObjectFile(Buff.get()).get())); DisassembleInputMachO2(Filename, MachOOF.get()); } @@ -288,12 +288,13 @@ static void DisassembleInputMachO2(StringRef Filename, // A separate DSym file path was specified, parse it as a macho file, // get the sections and supply it to the section name parsing machinery. if (!DSYMFile.empty()) { - std::unique_ptr<MemoryBuffer> Buf; - if (std::error_code ec = MemoryBuffer::getFileOrSTDIN(DSYMFile, Buf)) { - errs() << "llvm-objdump: " << Filename << ": " << ec.message() << '\n'; + ErrorOr<std::unique_ptr<MemoryBuffer>> Buf = + MemoryBuffer::getFileOrSTDIN(DSYMFile); + if (std::error_code EC = Buf.getError()) { + errs() << "llvm-objdump: " << Filename << ": " << EC.message() << '\n'; return; } - DbgObj = ObjectFile::createMachOObjectFile(Buf).get(); + DbgObj = ObjectFile::createMachOObjectFile(Buf.get()).get(); } // Setup the DIContext diff --git a/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp b/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp index fcda9e7f8a8..45734f4b7ba 100644 --- a/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp +++ b/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -175,14 +175,16 @@ static int printLineInfoForInput() { RuntimeDyld Dyld(&MemMgr); // Load the input memory buffer. - std::unique_ptr<MemoryBuffer> InputBuffer; - std::unique_ptr<ObjectImage> LoadedObject; - if (std::error_code ec = - MemoryBuffer::getFileOrSTDIN(InputFileList[i], InputBuffer)) - return Error("unable to read input: '" + ec.message() + "'"); + ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = + MemoryBuffer::getFileOrSTDIN(InputFileList[i]); + if (std::error_code EC = InputBuffer.getError()) + return Error("unable to read input: '" + EC.message() + "'"); + + std::unique_ptr<ObjectImage> LoadedObject; // Load the object file - LoadedObject.reset(Dyld.loadObject(new ObjectBuffer(InputBuffer.release()))); + LoadedObject.reset( + Dyld.loadObject(new ObjectBuffer(InputBuffer.get().release()))); if (!LoadedObject) { return Error(Dyld.getErrorString()); } @@ -236,14 +238,14 @@ static int executeInput() { InputFileList.push_back("-"); for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) { // Load the input memory buffer. - std::unique_ptr<MemoryBuffer> InputBuffer; + ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = + MemoryBuffer::getFileOrSTDIN(InputFileList[i]); + if (std::error_code EC = InputBuffer.getError()) + return Error("unable to read input: '" + EC.message() + "'"); std::unique_ptr<ObjectImage> LoadedObject; - if (std::error_code ec = - MemoryBuffer::getFileOrSTDIN(InputFileList[i], InputBuffer)) - return Error("unable to read input: '" + ec.message() + "'"); - // Load the object file - LoadedObject.reset(Dyld.loadObject(new ObjectBuffer(InputBuffer.release()))); + LoadedObject.reset( + Dyld.loadObject(new ObjectBuffer(InputBuffer.get().release()))); if (!LoadedObject) { return Error(Dyld.getErrorString()); } @@ -285,13 +287,14 @@ static int executeInput() { static int checkAllExpressions(RuntimeDyldChecker &Checker) { for (const auto& CheckerFileName : CheckFiles) { - std::unique_ptr<MemoryBuffer> CheckerFileBuf; - if (std::error_code EC = - MemoryBuffer::getFileOrSTDIN(CheckerFileName, CheckerFileBuf)) + ErrorOr<std::unique_ptr<MemoryBuffer>> CheckerFileBuf = + MemoryBuffer::getFileOrSTDIN(CheckerFileName); + if (std::error_code EC = CheckerFileBuf.getError()) return Error("unable to read input '" + CheckerFileName + "': " + EC.message()); - if (!Checker.checkAllRulesInBuffer("# rtdyld-check:", CheckerFileBuf.get())) + if (!Checker.checkAllRulesInBuffer("# rtdyld-check:", + CheckerFileBuf.get().get())) return Error("some checks in '" + CheckerFileName + "' failed"); } return 0; @@ -350,15 +353,15 @@ static int linkAndVerify() { InputFileList.push_back("-"); for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) { // Load the input memory buffer. - std::unique_ptr<MemoryBuffer> InputBuffer; - std::unique_ptr<ObjectImage> LoadedObject; - if (std::error_code ec = - MemoryBuffer::getFileOrSTDIN(InputFileList[i], InputBuffer)) - return Error("unable to read input: '" + ec.message() + "'"); + ErrorOr<std::unique_ptr<MemoryBuffer>> InputBuffer = + MemoryBuffer::getFileOrSTDIN(InputFileList[i]); + if (std::error_code EC = InputBuffer.getError()) + return Error("unable to read input: '" + EC.message() + "'"); + std::unique_ptr<ObjectImage> LoadedObject; // Load the object file LoadedObject.reset( - Dyld.loadObject(new ObjectBuffer(InputBuffer.release()))); + Dyld.loadObject(new ObjectBuffer(InputBuffer.get().release()))); if (!LoadedObject) { return Error(Dyld.getErrorString()); } diff --git a/llvm/tools/llvm-symbolizer/LLVMSymbolize.cpp b/llvm/tools/llvm-symbolizer/LLVMSymbolize.cpp index ebbae39a57a..c1d39efc1b8 100644 --- a/llvm/tools/llvm-symbolizer/LLVMSymbolize.cpp +++ b/llvm/tools/llvm-symbolizer/LLVMSymbolize.cpp @@ -220,10 +220,11 @@ static std::string getDarwinDWARFResourceForPath(const std::string &Path) { } static bool checkFileCRC(StringRef Path, uint32_t CRCHash) { - std::unique_ptr<MemoryBuffer> MB; - if (MemoryBuffer::getFileOrSTDIN(Path, MB)) + ErrorOr<std::unique_ptr<MemoryBuffer>> MB = + MemoryBuffer::getFileOrSTDIN(Path); + if (!MB) return false; - return !zlib::isAvailable() || CRCHash == zlib::crc32(MB->getBuffer()); + return !zlib::isAvailable() || CRCHash == zlib::crc32(MB.get()->getBuffer()); } static bool findDebugBinary(const std::string &OrigPath, diff --git a/llvm/tools/lto/lto.cpp b/llvm/tools/lto/lto.cpp index b3f5938b00d..b401f9a7f19 100644 --- a/llvm/tools/lto/lto.cpp +++ b/llvm/tools/lto/lto.cpp @@ -88,10 +88,10 @@ bool lto_module_is_object_file(const char* path) { bool lto_module_is_object_file_for_target(const char* path, const char* target_triplet_prefix) { - std::unique_ptr<MemoryBuffer> buffer; - if (MemoryBuffer::getFile(path, buffer)) + ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer = MemoryBuffer::getFile(path); + if (!Buffer) return false; - return LTOModule::isBitcodeForTarget(buffer.get(), target_triplet_prefix); + return LTOModule::isBitcodeForTarget(Buffer->get(), target_triplet_prefix); } bool lto_module_is_object_file_in_memory(const void* mem, size_t length) { diff --git a/llvm/tools/yaml2obj/yaml2obj.cpp b/llvm/tools/yaml2obj/yaml2obj.cpp index dd41951e7db..945fad1384a 100644 --- a/llvm/tools/yaml2obj/yaml2obj.cpp +++ b/llvm/tools/yaml2obj/yaml2obj.cpp @@ -91,8 +91,9 @@ int main(int argc, char **argv) { return 1; } - std::unique_ptr<MemoryBuffer> Buf; - if (MemoryBuffer::getFileOrSTDIN(Input, Buf)) + ErrorOr<std::unique_ptr<MemoryBuffer>> Buf = + MemoryBuffer::getFileOrSTDIN(Input); + if (!Buf) return 1; ConvertFuncPtr Convert = nullptr; @@ -105,7 +106,7 @@ int main(int argc, char **argv) { return 1; } - yaml::Input YIn(Buf->getBuffer()); + yaml::Input YIn(Buf.get()->getBuffer()); int Res = convertYAML(YIn, Out->os(), Convert); if (Res == 0) |