summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorYann Collet <cyan@fb.com>2017-09-30 17:35:55 (GMT)
committerYann Collet <cyan@fb.com>2017-09-30 17:35:55 (GMT)
commitf6b31bf0d082315103d2fb5fc8f2094be567bb63 (patch)
tree49b07bb8e7912ce929b67bd25bc4b5e3e8f62c09 /lib
parentceb868f4425a547bc5e08b6c80aaf4cc750fc9aa (diff)
downloadlz4-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')
-rw-r--r--lib/lz4.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/lib/lz4.c b/lib/lz4.c
index 707b94c..19967f2 100644
--- a/lib/lz4.c
+++ b/lib/lz4.c
@@ -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;