[lib] Make lib compatible with `-Wfall-through` excepting legacy
Switch to a macro `ZSTD_FALLTHROUGH;` instead of a comment. On supported compilers this uses an attribute, otherwise it becomes a comment. This is necessary to be compatible with clang's `-Wfall-through`, and gcc's `-Wfall-through=2` which don't support comments. Without this the linux build emits a bunch of warnings. Also add a test to CI to ensure that we don't regress.dev
parent
e3feec74d3
commit
189e87bcbe
|
@ -151,6 +151,18 @@ jobs:
|
||||||
make gcc8install
|
make gcc8install
|
||||||
CC=gcc-8 CFLAGS="-Werror" make -j all
|
CC=gcc-8 CFLAGS="-Werror" make -j all
|
||||||
|
|
||||||
|
implicit-fall-through:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: -Wimplicit-fallthrough build
|
||||||
|
run: |
|
||||||
|
make clean
|
||||||
|
CC=gcc MOREFLAGS="-Werror -Wimplicit-fallthrough=2 -O0" make -C lib -j libzstd.a ZSTD_LEGACY_SUPPORT=0
|
||||||
|
make clean
|
||||||
|
CC=clang MOREFLAGS="-Werror -Wimplicit-fallthrough -O0" make -C lib -j libzstd.a ZSTD_LEGACY_SUPPORT=0
|
||||||
|
|
||||||
|
|
||||||
visual-2019:
|
visual-2019:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
strategy:
|
strategy:
|
||||||
|
|
|
@ -51,6 +51,7 @@ libzstd:
|
||||||
-U_WIN32 \
|
-U_WIN32 \
|
||||||
-RZSTDLIB_VISIBILITY= \
|
-RZSTDLIB_VISIBILITY= \
|
||||||
-RZSTDERRORLIB_VISIBILITY= \
|
-RZSTDERRORLIB_VISIBILITY= \
|
||||||
|
-RZSTD_FALLTHROUGH=fallthrough \
|
||||||
-DZSTD_HAVE_WEAK_SYMBOLS=0 \
|
-DZSTD_HAVE_WEAK_SYMBOLS=0 \
|
||||||
-DZSTD_TRACE=0 \
|
-DZSTD_TRACE=0 \
|
||||||
-DZSTD_NO_TRACE
|
-DZSTD_NO_TRACE
|
||||||
|
|
|
@ -18,4 +18,6 @@
|
||||||
#define noinline __attribute__((noinline))
|
#define noinline __attribute__((noinline))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define fallthrough __attribute__((__fallthrough__))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -293,22 +293,22 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
|
||||||
switch(srcSize)
|
switch(srcSize)
|
||||||
{
|
{
|
||||||
case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
|
case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
|
||||||
/* fall-through */
|
ZSTD_FALLTHROUGH;
|
||||||
|
|
||||||
case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
|
case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
|
||||||
/* fall-through */
|
ZSTD_FALLTHROUGH;
|
||||||
|
|
||||||
case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
|
case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
|
||||||
/* fall-through */
|
ZSTD_FALLTHROUGH;
|
||||||
|
|
||||||
case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
|
case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
|
||||||
/* fall-through */
|
ZSTD_FALLTHROUGH;
|
||||||
|
|
||||||
case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
|
case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
|
||||||
/* fall-through */
|
ZSTD_FALLTHROUGH;
|
||||||
|
|
||||||
case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8;
|
case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8;
|
||||||
/* fall-through */
|
ZSTD_FALLTHROUGH;
|
||||||
|
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,6 +224,39 @@
|
||||||
# define __has_feature(x) 0
|
# define __has_feature(x) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* C-language Attributes are added in C23. */
|
||||||
|
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201710L) && defined(__has_c_attribute)
|
||||||
|
# define ZSTD_HAS_C_ATTRIBUTE(x) __has_c_attribute(x)
|
||||||
|
#else
|
||||||
|
# define ZSTD_HAS_C_ATTRIBUTE(x) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Only use C++ attributes in C++. Some compilers report support for C++
|
||||||
|
* attributes when compiling with C.
|
||||||
|
*/
|
||||||
|
#if defined(__cplusplus) && defined(__has_cpp_attribute)
|
||||||
|
# define ZSTD_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
|
||||||
|
#else
|
||||||
|
# define ZSTD_HAS_CPP_ATTRIBUTE(x) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define ZSTD_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute.
|
||||||
|
* - C23: https://en.cppreference.com/w/c/language/attributes/fallthrough
|
||||||
|
* - CPP17: https://en.cppreference.com/w/cpp/language/attributes/fallthrough
|
||||||
|
* - Else: __attribute__((__fallthrough__))
|
||||||
|
*/
|
||||||
|
#ifndef ZSTD_FALLTHROUGH
|
||||||
|
# if ZSTD_HAS_C_ATTRIBUTE(fallthrough)
|
||||||
|
# define ZSTD_FALLTHROUGH [[fallthrough]]
|
||||||
|
# elif ZSTD_HAS_CPP_ATTRIBUTE(fallthrough)
|
||||||
|
# define ZSTD_FALLTHROUGH [[fallthrough]]
|
||||||
|
# elif __has_attribute(__fallthrough__)
|
||||||
|
# define ZSTD_FALLTHROUGH __attribute__((__fallthrough__))
|
||||||
|
# else
|
||||||
|
# define ZSTD_FALLTHROUGH
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* detects whether we are being compiled under msan */
|
/* detects whether we are being compiled under msan */
|
||||||
#ifndef ZSTD_MEMORY_SANITIZER
|
#ifndef ZSTD_MEMORY_SANITIZER
|
||||||
# if __has_feature(memory_sanitizer)
|
# if __has_feature(memory_sanitizer)
|
||||||
|
|
|
@ -989,12 +989,12 @@ HUF_compress1X_usingCTable_internal_body(void* dst, size_t dstSize,
|
||||||
case 11:
|
case 11:
|
||||||
HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 2, /* kFastFlush */ 1, /* kLastFast */ 0);
|
HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 2, /* kFastFlush */ 1, /* kLastFast */ 0);
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10: ZSTD_FALLTHROUGH;
|
||||||
case 9:
|
case 9: ZSTD_FALLTHROUGH;
|
||||||
case 8:
|
case 8:
|
||||||
HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 2, /* kFastFlush */ 1, /* kLastFast */ 1);
|
HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 2, /* kFastFlush */ 1, /* kLastFast */ 1);
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7: ZSTD_FALLTHROUGH;
|
||||||
default:
|
default:
|
||||||
HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 3, /* kFastFlush */ 1, /* kLastFast */ 1);
|
HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 3, /* kFastFlush */ 1, /* kLastFast */ 1);
|
||||||
break;
|
break;
|
||||||
|
@ -1016,7 +1016,7 @@ HUF_compress1X_usingCTable_internal_body(void* dst, size_t dstSize,
|
||||||
case 7:
|
case 7:
|
||||||
HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 8, /* kFastFlush */ 1, /* kLastFast */ 0);
|
HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 8, /* kFastFlush */ 1, /* kLastFast */ 0);
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6: ZSTD_FALLTHROUGH;
|
||||||
default:
|
default:
|
||||||
HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 9, /* kFastFlush */ 1, /* kLastFast */ 1);
|
HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 9, /* kFastFlush */ 1, /* kLastFast */ 1);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -4023,7 +4023,9 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
|
||||||
if (!singleSegment) op[pos++] = windowLogByte;
|
if (!singleSegment) op[pos++] = windowLogByte;
|
||||||
switch(dictIDSizeCode)
|
switch(dictIDSizeCode)
|
||||||
{
|
{
|
||||||
default: assert(0); /* impossible */
|
default:
|
||||||
|
assert(0); /* impossible */
|
||||||
|
ZSTD_FALLTHROUGH;
|
||||||
case 0 : break;
|
case 0 : break;
|
||||||
case 1 : op[pos] = (BYTE)(dictID); pos++; break;
|
case 1 : op[pos] = (BYTE)(dictID); pos++; break;
|
||||||
case 2 : MEM_writeLE16(op+pos, (U16)dictID); pos+=2; break;
|
case 2 : MEM_writeLE16(op+pos, (U16)dictID); pos+=2; break;
|
||||||
|
@ -4031,7 +4033,9 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
|
||||||
}
|
}
|
||||||
switch(fcsCode)
|
switch(fcsCode)
|
||||||
{
|
{
|
||||||
default: assert(0); /* impossible */
|
default:
|
||||||
|
assert(0); /* impossible */
|
||||||
|
ZSTD_FALLTHROUGH;
|
||||||
case 0 : if (singleSegment) op[pos++] = (BYTE)(pledgedSrcSize); break;
|
case 0 : if (singleSegment) op[pos++] = (BYTE)(pledgedSrcSize); break;
|
||||||
case 1 : MEM_writeLE16(op+pos, (U16)(pledgedSrcSize-256)); pos+=2; break;
|
case 1 : MEM_writeLE16(op+pos, (U16)(pledgedSrcSize-256)); pos+=2; break;
|
||||||
case 2 : MEM_writeLE32(op+pos, (U32)(pledgedSrcSize)); pos+=4; break;
|
case 2 : MEM_writeLE32(op+pos, (U32)(pledgedSrcSize)); pos+=4; break;
|
||||||
|
@ -5435,7 +5439,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
|
||||||
zcs->outBuffFlushedSize = 0;
|
zcs->outBuffFlushedSize = 0;
|
||||||
zcs->streamStage = zcss_flush; /* pass-through to flush stage */
|
zcs->streamStage = zcss_flush; /* pass-through to flush stage */
|
||||||
}
|
}
|
||||||
/* fall-through */
|
ZSTD_FALLTHROUGH;
|
||||||
case zcss_flush:
|
case zcss_flush:
|
||||||
DEBUGLOG(5, "flush stage");
|
DEBUGLOG(5, "flush stage");
|
||||||
assert(zcs->appliedParams.outBufferMode == ZSTD_bm_buffered);
|
assert(zcs->appliedParams.outBufferMode == ZSTD_bm_buffered);
|
||||||
|
|
|
@ -560,7 +560,7 @@ MEM_STATIC int ZSTD_literalsCompressionIsDisabled(const ZSTD_CCtx_params* cctxPa
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
assert(0 /* impossible: pre-validated */);
|
assert(0 /* impossible: pre-validated */);
|
||||||
/* fall-through */
|
ZSTD_FALLTHROUGH;
|
||||||
case ZSTD_ps_auto:
|
case ZSTD_ps_auto:
|
||||||
return (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0);
|
return (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,8 +244,6 @@ _search_next_long:
|
||||||
while (((ip>anchor) & (match>prefixLowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
|
while (((ip>anchor) & (match>prefixLowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fall-through */
|
|
||||||
|
|
||||||
_match_found:
|
_match_found:
|
||||||
offset_2 = offset_1;
|
offset_2 = offset_1;
|
||||||
offset_1 = offset;
|
offset_1 = offset;
|
||||||
|
|
|
@ -479,7 +479,9 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s
|
||||||
}
|
}
|
||||||
switch(dictIDSizeCode)
|
switch(dictIDSizeCode)
|
||||||
{
|
{
|
||||||
default: assert(0); /* impossible */
|
default:
|
||||||
|
assert(0); /* impossible */
|
||||||
|
ZSTD_FALLTHROUGH;
|
||||||
case 0 : break;
|
case 0 : break;
|
||||||
case 1 : dictID = ip[pos]; pos++; break;
|
case 1 : dictID = ip[pos]; pos++; break;
|
||||||
case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break;
|
case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break;
|
||||||
|
@ -487,7 +489,9 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s
|
||||||
}
|
}
|
||||||
switch(fcsID)
|
switch(fcsID)
|
||||||
{
|
{
|
||||||
default: assert(0); /* impossible */
|
default:
|
||||||
|
assert(0); /* impossible */
|
||||||
|
ZSTD_FALLTHROUGH;
|
||||||
case 0 : if (singleSegment) frameContentSize = ip[pos]; break;
|
case 0 : if (singleSegment) frameContentSize = ip[pos]; break;
|
||||||
case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break;
|
case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break;
|
||||||
case 2 : frameContentSize = MEM_readLE32(ip+pos); break;
|
case 2 : frameContentSize = MEM_readLE32(ip+pos); break;
|
||||||
|
@ -1052,7 +1056,7 @@ static ZSTD_DDict const* ZSTD_getDDict(ZSTD_DCtx* dctx)
|
||||||
switch (dctx->dictUses) {
|
switch (dctx->dictUses) {
|
||||||
default:
|
default:
|
||||||
assert(0 /* Impossible */);
|
assert(0 /* Impossible */);
|
||||||
/* fall-through */
|
ZSTD_FALLTHROUGH;
|
||||||
case ZSTD_dont_use:
|
case ZSTD_dont_use:
|
||||||
ZSTD_clearDict(dctx);
|
ZSTD_clearDict(dctx);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1116,7 +1120,9 @@ ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
|
||||||
{
|
{
|
||||||
default: /* should not happen */
|
default: /* should not happen */
|
||||||
assert(0);
|
assert(0);
|
||||||
|
ZSTD_FALLTHROUGH;
|
||||||
case ZSTDds_getFrameHeaderSize:
|
case ZSTDds_getFrameHeaderSize:
|
||||||
|
ZSTD_FALLTHROUGH;
|
||||||
case ZSTDds_decodeFrameHeader:
|
case ZSTDds_decodeFrameHeader:
|
||||||
return ZSTDnit_frameHeader;
|
return ZSTDnit_frameHeader;
|
||||||
case ZSTDds_decodeBlockHeader:
|
case ZSTDds_decodeBlockHeader:
|
||||||
|
@ -1128,6 +1134,7 @@ ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
|
||||||
case ZSTDds_checkChecksum:
|
case ZSTDds_checkChecksum:
|
||||||
return ZSTDnit_checksum;
|
return ZSTDnit_checksum;
|
||||||
case ZSTDds_decodeSkippableHeader:
|
case ZSTDds_decodeSkippableHeader:
|
||||||
|
ZSTD_FALLTHROUGH;
|
||||||
case ZSTDds_skipFrame:
|
case ZSTDds_skipFrame:
|
||||||
return ZSTDnit_skippableFrame;
|
return ZSTDnit_skippableFrame;
|
||||||
}
|
}
|
||||||
|
@ -1943,7 +1950,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
||||||
zds->legacyVersion = 0;
|
zds->legacyVersion = 0;
|
||||||
zds->hostageByte = 0;
|
zds->hostageByte = 0;
|
||||||
zds->expectedOutBuffer = *output;
|
zds->expectedOutBuffer = *output;
|
||||||
/* fall-through */
|
ZSTD_FALLTHROUGH;
|
||||||
|
|
||||||
case zdss_loadHeader :
|
case zdss_loadHeader :
|
||||||
DEBUGLOG(5, "stage zdss_loadHeader (srcSize : %u)", (U32)(iend - ip));
|
DEBUGLOG(5, "stage zdss_loadHeader (srcSize : %u)", (U32)(iend - ip));
|
||||||
|
@ -2081,7 +2088,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
||||||
zds->outBuffSize = neededOutBuffSize;
|
zds->outBuffSize = neededOutBuffSize;
|
||||||
} } }
|
} } }
|
||||||
zds->streamStage = zdss_read;
|
zds->streamStage = zdss_read;
|
||||||
/* fall-through */
|
ZSTD_FALLTHROUGH;
|
||||||
|
|
||||||
case zdss_read:
|
case zdss_read:
|
||||||
DEBUGLOG(5, "stage zdss_read");
|
DEBUGLOG(5, "stage zdss_read");
|
||||||
|
@ -2100,7 +2107,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
||||||
} }
|
} }
|
||||||
if (ip==iend) { someMoreWork = 0; break; } /* no more input */
|
if (ip==iend) { someMoreWork = 0; break; } /* no more input */
|
||||||
zds->streamStage = zdss_load;
|
zds->streamStage = zdss_load;
|
||||||
/* fall-through */
|
ZSTD_FALLTHROUGH;
|
||||||
|
|
||||||
case zdss_load:
|
case zdss_load:
|
||||||
{ size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds);
|
{ size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds);
|
||||||
|
|
|
@ -90,7 +90,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
||||||
case set_repeat:
|
case set_repeat:
|
||||||
DEBUGLOG(5, "set_repeat flag : re-using stats from previous compressed literals block");
|
DEBUGLOG(5, "set_repeat flag : re-using stats from previous compressed literals block");
|
||||||
RETURN_ERROR_IF(dctx->litEntropy==0, dictionary_corrupted, "");
|
RETURN_ERROR_IF(dctx->litEntropy==0, dictionary_corrupted, "");
|
||||||
/* fall-through */
|
ZSTD_FALLTHROUGH;
|
||||||
|
|
||||||
case set_compressed:
|
case set_compressed:
|
||||||
RETURN_ERROR_IF(srcSize < 5, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3");
|
RETURN_ERROR_IF(srcSize < 5, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3");
|
||||||
|
|
Loading…
Reference in New Issue