From 167ca4ae7eef7d8b3539a1a711d53b09e3105099 Mon Sep 17 00:00:00 2001 From: George Rimar Date: Tue, 17 Jan 2017 15:45:07 +0000 Subject: [PATCH] Recommit r292214 "[Support/Compression] - Change zlib API to return Error instead of custom status" No any changes, will follow up with D28807 commit containing APLi change for clang to fix build issues happened. Original commit message: [Support/Compression] - Change zlib API to return Error instead of custom status. Previously API returned custom enum values. Patch changes it to return Error with string description. That should help users to report errors in universal way. Differential revision: https://reviews.llvm.org/D28684 llvm-svn: 292226 --- llvm/include/llvm/Support/Compression.h | 24 +++---- llvm/lib/MC/ELFObjectWriter.cpp | 9 +-- llvm/lib/Object/Decompressor.cpp | 5 +- llvm/lib/ProfileData/InstrProf.cpp | 17 +++-- llvm/lib/Support/Compression.cpp | 83 ++++++++++++---------- llvm/unittests/Support/CompressionTest.cpp | 17 +++-- 6 files changed, 83 insertions(+), 72 deletions(-) diff --git a/llvm/include/llvm/Support/Compression.h b/llvm/include/llvm/Support/Compression.h index 5bf7031fe9f90..2d191abe4b1af 100644 --- a/llvm/include/llvm/Support/Compression.h +++ b/llvm/include/llvm/Support/Compression.h @@ -18,6 +18,7 @@ namespace llvm { template class SmallVectorImpl; +class Error; class StringRef; namespace zlib { @@ -29,26 +30,17 @@ enum CompressionLevel { BestSizeCompression }; -enum Status { - StatusOK, - StatusUnsupported, // zlib is unavailable - StatusOutOfMemory, // there was not enough memory - StatusBufferTooShort, // there was not enough room in the output buffer - StatusInvalidArg, // invalid input parameter - StatusInvalidData // data was corrupted or incomplete -}; - bool isAvailable(); -Status compress(StringRef InputBuffer, SmallVectorImpl &CompressedBuffer, - CompressionLevel Level = DefaultCompression); +Error compress(StringRef InputBuffer, SmallVectorImpl &CompressedBuffer, + CompressionLevel Level = DefaultCompression); -Status uncompress(StringRef InputBuffer, char *UncompressedBuffer, - size_t &UncompressedSize); +Error uncompress(StringRef InputBuffer, char *UncompressedBuffer, + size_t &UncompressedSize); -Status uncompress(StringRef InputBuffer, - SmallVectorImpl &UncompressedBuffer, - size_t UncompressedSize); +Error uncompress(StringRef InputBuffer, + SmallVectorImpl &UncompressedBuffer, + size_t UncompressedSize); uint32_t crc32(StringRef Buffer); diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index a8c88dda69362..0e02cdb4ca034 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -32,6 +32,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/ELF.h" #include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/StringSaver.h" #include @@ -1037,10 +1038,10 @@ void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec, setStream(OldStream); SmallVector CompressedContents; - zlib::Status Success = zlib::compress( - StringRef(UncompressedData.data(), UncompressedData.size()), - CompressedContents); - if (Success != zlib::StatusOK) { + if (Error E = zlib::compress( + StringRef(UncompressedData.data(), UncompressedData.size()), + CompressedContents)) { + consumeError(std::move(E)); getStream() << UncompressedData; return; } diff --git a/llvm/lib/Object/Decompressor.cpp b/llvm/lib/Object/Decompressor.cpp index bca41fd9f4875..0be602b1fc1ab 100644 --- a/llvm/lib/Object/Decompressor.cpp +++ b/llvm/lib/Object/Decompressor.cpp @@ -95,8 +95,5 @@ Error Decompressor::decompress(SmallString<32> &Out) { Error Decompressor::decompress(MutableArrayRef Buffer) { size_t Size = Buffer.size(); - zlib::Status Status = zlib::uncompress(SectionData, Buffer.data(), Size); - if (Status != zlib::StatusOK) - return createError("decompression failed"); - return Error::success(); + return zlib::uncompress(SectionData, Buffer.data(), Size); } diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp index 74acd9e5e207f..eb676602632b6 100644 --- a/llvm/lib/ProfileData/InstrProf.cpp +++ b/llvm/lib/ProfileData/InstrProf.cpp @@ -271,12 +271,12 @@ Error collectPGOFuncNameStrings(const std::vector &NameStrs, } SmallString<128> CompressedNameStrings; - zlib::Status Success = - zlib::compress(StringRef(UncompressedNameStrings), CompressedNameStrings, - zlib::BestSizeCompression); - - if (Success != zlib::StatusOK) + Error E = zlib::compress(StringRef(UncompressedNameStrings), + CompressedNameStrings, zlib::BestSizeCompression); + if (E) { + consumeError(std::move(E)); return make_error(instrprof_error::compress_failed); + } return WriteStringToResult(CompressedNameStrings.size(), CompressedNameStrings); @@ -315,9 +315,12 @@ Error readPGOFuncNameStrings(StringRef NameStrings, InstrProfSymtab &Symtab) { if (isCompressed) { StringRef CompressedNameStrings(reinterpret_cast(P), CompressedSize); - if (zlib::uncompress(CompressedNameStrings, UncompressedNameStrings, - UncompressedSize) != zlib::StatusOK) + if (Error E = + zlib::uncompress(CompressedNameStrings, UncompressedNameStrings, + UncompressedSize)) { + consumeError(std::move(E)); return make_error(instrprof_error::uncompress_failed); + } P += CompressedSize; NameStrings = StringRef(UncompressedNameStrings.data(), UncompressedNameStrings.size()); diff --git a/llvm/lib/Support/Compression.cpp b/llvm/lib/Support/Compression.cpp index 5d556462e89c2..c279d10f6c614 100644 --- a/llvm/lib/Support/Compression.cpp +++ b/llvm/lib/Support/Compression.cpp @@ -16,6 +16,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Config/config.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #if LLVM_ENABLE_ZLIB == 1 && HAVE_ZLIB_H #include @@ -24,6 +25,10 @@ using namespace llvm; #if LLVM_ENABLE_ZLIB == 1 && HAVE_LIBZ +static Error createError(StringRef Err) { + return make_error(Err, inconvertibleErrorCode()); +} + static int encodeZlibCompressionLevel(zlib::CompressionLevel Level) { switch (Level) { case zlib::NoCompression: return 0; @@ -34,53 +39,59 @@ static int encodeZlibCompressionLevel(zlib::CompressionLevel Level) { llvm_unreachable("Invalid zlib::CompressionLevel!"); } -static zlib::Status encodeZlibReturnValue(int ReturnValue) { - switch (ReturnValue) { - case Z_OK: return zlib::StatusOK; - case Z_MEM_ERROR: return zlib::StatusOutOfMemory; - case Z_BUF_ERROR: return zlib::StatusBufferTooShort; - case Z_STREAM_ERROR: return zlib::StatusInvalidArg; - case Z_DATA_ERROR: return zlib::StatusInvalidData; - default: llvm_unreachable("unknown zlib return status!"); +static StringRef convertZlibCodeToString(int Code) { + switch (Code) { + case Z_MEM_ERROR: + return "zlib error: Z_MEM_ERROR"; + case Z_BUF_ERROR: + return "zlib error: Z_BUF_ERROR"; + case Z_STREAM_ERROR: + return "zlib error: Z_STREAM_ERROR"; + case Z_DATA_ERROR: + return "zlib error: Z_DATA_ERROR"; + case Z_OK: + default: + llvm_unreachable("unknown or unexpected zlib status code"); } } bool zlib::isAvailable() { return true; } -zlib::Status zlib::compress(StringRef InputBuffer, - SmallVectorImpl &CompressedBuffer, - CompressionLevel Level) { + +Error zlib::compress(StringRef InputBuffer, + SmallVectorImpl &CompressedBuffer, + CompressionLevel Level) { unsigned long CompressedSize = ::compressBound(InputBuffer.size()); CompressedBuffer.resize(CompressedSize); int CLevel = encodeZlibCompressionLevel(Level); - Status Res = encodeZlibReturnValue(::compress2( - (Bytef *)CompressedBuffer.data(), &CompressedSize, - (const Bytef *)InputBuffer.data(), InputBuffer.size(), CLevel)); + int Res = ::compress2((Bytef *)CompressedBuffer.data(), &CompressedSize, + (const Bytef *)InputBuffer.data(), InputBuffer.size(), + CLevel); // Tell MemorySanitizer that zlib output buffer is fully initialized. // This avoids a false report when running LLVM with uninstrumented ZLib. __msan_unpoison(CompressedBuffer.data(), CompressedSize); CompressedBuffer.resize(CompressedSize); - return Res; + return Res ? createError(convertZlibCodeToString(Res)) : Error::success(); } -zlib::Status zlib::uncompress(StringRef InputBuffer, char *UncompressedBuffer, - size_t &UncompressedSize) { - Status Res = encodeZlibReturnValue( +Error zlib::uncompress(StringRef InputBuffer, char *UncompressedBuffer, + size_t &UncompressedSize) { + int Res = ::uncompress((Bytef *)UncompressedBuffer, (uLongf *)&UncompressedSize, - (const Bytef *)InputBuffer.data(), InputBuffer.size())); + (const Bytef *)InputBuffer.data(), InputBuffer.size()); // Tell MemorySanitizer that zlib output buffer is fully initialized. // This avoids a false report when running LLVM with uninstrumented ZLib. __msan_unpoison(UncompressedBuffer, UncompressedSize); - return Res; + return Res ? createError(convertZlibCodeToString(Res)) : Error::success(); } -zlib::Status zlib::uncompress(StringRef InputBuffer, - SmallVectorImpl &UncompressedBuffer, - size_t UncompressedSize) { +Error zlib::uncompress(StringRef InputBuffer, + SmallVectorImpl &UncompressedBuffer, + size_t UncompressedSize) { UncompressedBuffer.resize(UncompressedSize); - Status Res = + Error E = uncompress(InputBuffer, UncompressedBuffer.data(), UncompressedSize); UncompressedBuffer.resize(UncompressedSize); - return Res; + return E; } uint32_t zlib::crc32(StringRef Buffer) { @@ -89,19 +100,19 @@ uint32_t zlib::crc32(StringRef Buffer) { #else bool zlib::isAvailable() { return false; } -zlib::Status zlib::compress(StringRef InputBuffer, - SmallVectorImpl &CompressedBuffer, - CompressionLevel Level) { - return zlib::StatusUnsupported; +Error zlib::compress(StringRef InputBuffer, + SmallVectorImpl &CompressedBuffer, + CompressionLevel Level) { + llvm_unreachable("zlib::compress is unavailable"); } -zlib::Status zlib::uncompress(StringRef InputBuffer, char *UncompressedBuffer, - size_t &UncompressedSize) { - return zlib::StatusUnsupported; +Error zlib::uncompress(StringRef InputBuffer, char *UncompressedBuffer, + size_t &UncompressedSize) { + llvm_unreachable("zlib::uncompress is unavailable"); } -zlib::Status zlib::uncompress(StringRef InputBuffer, - SmallVectorImpl &UncompressedBuffer, - size_t UncompressedSize) { - return zlib::StatusUnsupported; +Error zlib::uncompress(StringRef InputBuffer, + SmallVectorImpl &UncompressedBuffer, + size_t UncompressedSize) { + llvm_unreachable("zlib::uncompress is unavailable"); } uint32_t zlib::crc32(StringRef Buffer) { llvm_unreachable("zlib::crc32 is unavailable"); diff --git a/llvm/unittests/Support/CompressionTest.cpp b/llvm/unittests/Support/CompressionTest.cpp index 36b84d85f22be..18a6175460d36 100644 --- a/llvm/unittests/Support/CompressionTest.cpp +++ b/llvm/unittests/Support/CompressionTest.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/Compression.h" +#include "llvm/Support/Error.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/Config/config.h" @@ -26,15 +27,21 @@ namespace { void TestZlibCompression(StringRef Input, zlib::CompressionLevel Level) { SmallString<32> Compressed; SmallString<32> Uncompressed; - EXPECT_EQ(zlib::StatusOK, zlib::compress(Input, Compressed, Level)); + + Error E = zlib::compress(Input, Compressed, Level); + EXPECT_FALSE(E); + consumeError(std::move(E)); + // Check that uncompressed buffer is the same as original. - EXPECT_EQ(zlib::StatusOK, - zlib::uncompress(Compressed, Uncompressed, Input.size())); + E = zlib::uncompress(Compressed, Uncompressed, Input.size()); + EXPECT_FALSE(E); + consumeError(std::move(E)); + EXPECT_EQ(Input, Uncompressed); if (Input.size() > 0) { // Uncompression fails if expected length is too short. - EXPECT_EQ(zlib::StatusBufferTooShort, - zlib::uncompress(Compressed, Uncompressed, Input.size() - 1)); + E = zlib::uncompress(Compressed, Uncompressed, Input.size() - 1); + EXPECT_EQ("zlib error: Z_BUF_ERROR", llvm::toString(std::move(E))); } }