diff options
author | Yann Collet <cyan@fb.com> | 2017-09-30 17:35:55 (GMT) |
---|---|---|
committer | Yann Collet <cyan@fb.com> | 2017-09-30 17:35:55 (GMT) |
commit | f6b31bf0d082315103d2fb5fc8f2094be567bb63 (patch) | |
tree | 49b07bb8e7912ce929b67bd25bc4b5e3e8f62c09 /lib/lz4.c | |
parent | ceb868f4425a547bc5e08b6c80aaf4cc750fc9aa (diff) | |
download | lz4-f6b31bf0d082315103d2fb5fc8f2094be567bb63.zip lz4-f6b31bf0d082315103d2fb5fc8f2094be567bb63.tar.gz lz4-f6b31bf0d082315103d2fb5fc8f2094be567bb63.tar.bz2 |
fix #404
static analyzer `cppcheck` complains about a shift-by-32 on a 32 bits value,
which is an undefined behavior.
However, the flagged code path is never triggered in 32-bits mode,
(actually, it's not even generated if DCE kicks in),
the shift-by-32 is necessarily performed on a 64-bits value.
While it doesn't change anything regarding lz4 code generation, for both 32 and 64 bits mode,
(can be checked by md5sum on the generated binary),
the shift has been rewritten in a way which should please this static analyzer,
since it now pretends to shift by 16 on 32-bits cpu (note : it doesn't matter since the code will not even be generated in this case).
Note : this is a blind fix, the new code has not been tested with cppcheck, because cppcheck only works on Windows.
Other static analyzer, such as scan-build, do not trigger this false positive.
Diffstat (limited to 'lib/lz4.c')
-rw-r--r-- | lib/lz4.c | 7 |
1 files changed, 5 insertions, 2 deletions
@@ -334,7 +334,7 @@ static unsigned LZ4_NbCommonBytes (register reg_t val) # endif } } else /* Big Endian CPU */ { - if (sizeof(val)==8) { + if (sizeof(val)==8) { /* 64-bits */ # if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r = 0; _BitScanReverse64( &r, val ); @@ -342,8 +342,11 @@ static unsigned LZ4_NbCommonBytes (register reg_t val) # elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_clzll((U64)val) >> 3); # else + static const U32 by32 = sizeof(val)*4; /* 32 on 64 bits (goal), 16 on 32 bits. + Just to avoid some static analyzer complaining about shift by 32 on 32-bits target. + Note that this code path is never triggered in 32-bits mode. */ unsigned r; - if (!(val>>32)) { r=4; } else { r=0; val>>=32; } + if (!(val>>by32)) { r=4; } else { r=0; val>>=by32; } if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; } r += (!val); return r; |