Fixed issues with MSVC emulations of clz and clzll.
Both clang-cl and Clang/C2 #define _MSC_VER but also have support for __builtin_clz and __builtin_clzll, leading to duplicate macro definition warnings. Emulation of clz using _BitScanReverse is suppressed if the builtins are already available. Additionally, the value of the output parameter of _BitScanReverse is undefined if the input value is 0, which is avoided by construction, so the code analysis warning for using uninitialized data is now suppressed.
This commit is contained in:
parent
251a0869be
commit
7185e96da1
33
format.h
33
format.h
@ -75,7 +75,7 @@ typedef __int64 intmax_t;
|
||||
# define FMT_API
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#if defined(_MSC_VER)
|
||||
# include <intrin.h> // _BitScanReverse, _BitScanReverse64
|
||||
|
||||
namespace fmt {
|
||||
@ -84,9 +84,14 @@ namespace internal {
|
||||
inline uint32_t clz(uint32_t x) {
|
||||
unsigned long r = 0;
|
||||
_BitScanReverse(&r, x);
|
||||
|
||||
assert(x != 0);
|
||||
// Static analysis complains about using uninitialized data
|
||||
// "r", but the only way that can happen is if "x" is 0,
|
||||
// which the callers guarantee to not happen.
|
||||
#pragma warning(suppress: 6102)
|
||||
return 31 - r;
|
||||
}
|
||||
# define FMT_BUILTIN_CLZ(n) fmt::internal::clz(n)
|
||||
|
||||
# ifdef _WIN64
|
||||
# pragma intrinsic(_BitScanReverse64)
|
||||
@ -104,9 +109,14 @@ inline uint32_t clzll(uint64_t x) {
|
||||
// Scan the low 32 bits.
|
||||
_BitScanReverse(&r, static_cast<uint32_t>(x));
|
||||
# endif
|
||||
|
||||
assert(x != 0);
|
||||
// Static analysis complains about using uninitialized data
|
||||
// "r", but the only way that can happen is if "x" is 0,
|
||||
// which the callers guarantee to not happen.
|
||||
#pragma warning(suppress: 6102)
|
||||
return 63 - r;
|
||||
}
|
||||
# define FMT_BUILTIN_CLZLL(n) fmt::internal::clzll(n)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -801,6 +811,23 @@ typedef BasicData<> Data;
|
||||
# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
// Some compilers masquerade as both MSVC and GCC-likes or
|
||||
// otherwise support __builtin_clz and __builtin_clzll, so
|
||||
// only define FMT_BUILTIN_CLZ using the MSVC intrinsics
|
||||
// if the clz and clzll builtins are not available.
|
||||
#if !defined(FMT_BUILTIN_CLZ)
|
||||
# define FMT_BUILTIN_CLZ(n) fmt::internal::clz(n)
|
||||
#endif
|
||||
|
||||
#if !defined(FMT_BUILTIN_CLZLL)
|
||||
# define FMT_BUILTIN_CLZLL(n) fmt::internal::clzll(n)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef FMT_BUILTIN_CLZLL
|
||||
// Returns the number of decimal digits in n. Leading zeros are not counted
|
||||
// except for n == 0 in which case count_digits returns 1.
|
||||
|
Loading…
Reference in New Issue
Block a user