From cb7052bfdabeed3b56d6ac32b20807856b5177d4 Mon Sep 17 00:00:00 2001 From: Jun He Date: Mon, 9 Mar 2020 16:20:52 +0800 Subject: [PATCH] Replace RAPIDJSON_CLZLL with internal clzll RAPIDJSON_CLZLL is defined as macro of __builtin_clzll when using gcc to compile. This introduces two issues: 1. in gcc __builtin_clzll returns int, not uint32_t. 2. __builtin_clzll return is undefined when input x is 0 See: https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html This patch removes RAPIDJSON_CLZLL, merges __builtin_clzll to internal clzll with input check and return value explicit cast. Change-Id: Iac4b355dc5e5b4ed9b3f35a640b6b5537e76f22c Signed-off-by: Jun He --- include/rapidjson/internal/clzll.h | 11 +++++------ include/rapidjson/internal/diyfp.h | 2 +- include/rapidjson/reader.h | 20 ++++++++++---------- include/rapidjson/writer.h | 4 ++-- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/include/rapidjson/internal/clzll.h b/include/rapidjson/internal/clzll.h index abe44dfc5..6cd792349 100644 --- a/include/rapidjson/internal/clzll.h +++ b/include/rapidjson/internal/clzll.h @@ -29,10 +29,6 @@ RAPIDJSON_NAMESPACE_BEGIN namespace internal { -#if (defined(__GNUC__) && __GNUC__ >= 4) || RAPIDJSON_HAS_BUILTIN(__builtin_clzll) -#define RAPIDJSON_CLZLL __builtin_clzll -#else - inline uint32_t clzll(uint64_t x) { // Passing 0 to __builtin_clzll is UB in GCC and results in an // infinite loop in the software implementation. @@ -52,7 +48,11 @@ inline uint32_t clzll(uint64_t x) { #endif // _WIN64 return 63 - r; +#elif (defined(__GNUC__) && __GNUC__ >= 4) || RAPIDJSON_HAS_BUILTIN(__builtin_clzll) + // __builtin_clzll wrapper + return static_cast(__builtin_clzll(x)); #else + // naive version uint32_t r; while (!(x & (static_cast(1) << 63))) { x <<= 1; @@ -64,9 +64,8 @@ inline uint32_t clzll(uint64_t x) { } #define RAPIDJSON_CLZLL RAPIDJSON_NAMESPACE::internal::clzll -#endif // (defined(__GNUC__) && __GNUC__ >= 4) || RAPIDJSON_HAS_BUILTIN(__builtin_clzll) } // namespace internal RAPIDJSON_NAMESPACE_END -#endif // RAPIDJSON_CLZLL_H_ \ No newline at end of file +#endif // RAPIDJSON_CLZLL_H_ diff --git a/include/rapidjson/internal/diyfp.h b/include/rapidjson/internal/diyfp.h index f46059a0f..8f7d853a3 100644 --- a/include/rapidjson/internal/diyfp.h +++ b/include/rapidjson/internal/diyfp.h @@ -100,7 +100,7 @@ struct DiyFp { } DiyFp Normalize() const { - int s = static_cast(RAPIDJSON_CLZLL(f)); + int s = static_cast(clzll(f)); return DiyFp(f << s, e - s); } diff --git a/include/rapidjson/reader.h b/include/rapidjson/reader.h index 2d73b1915..0f85032a7 100644 --- a/include/rapidjson/reader.h +++ b/include/rapidjson/reader.h @@ -450,11 +450,11 @@ inline const char *SkipWhitespace_SIMD(const char* p) { if (low == 0) { if (high != 0) { - uint32_t lz = RAPIDJSON_CLZLL(high); + uint32_t lz = internal::clzll(high); return p + 8 + (lz >> 3); } } else { - uint32_t lz = RAPIDJSON_CLZLL(low); + uint32_t lz = internal::clzll(low); return p + (lz >> 3); } } @@ -486,11 +486,11 @@ inline const char *SkipWhitespace_SIMD(const char* p, const char* end) { if (low == 0) { if (high != 0) { - uint32_t lz = RAPIDJSON_CLZLL(high); + uint32_t lz = internal::clzll(high); return p + 8 + (lz >> 3); } } else { - uint32_t lz = RAPIDJSON_CLZLL(low); + uint32_t lz = internal::clzll(low); return p + (lz >> 3); } } @@ -1257,12 +1257,12 @@ class GenericReader { bool escaped = false; if (low == 0) { if (high != 0) { - uint32_t lz = RAPIDJSON_CLZLL(high); + uint32_t lz = internal::clzll(high); length = 8 + (lz >> 3); escaped = true; } } else { - uint32_t lz = RAPIDJSON_CLZLL(low); + uint32_t lz = internal::clzll(low); length = lz >> 3; escaped = true; } @@ -1327,12 +1327,12 @@ class GenericReader { bool escaped = false; if (low == 0) { if (high != 0) { - uint32_t lz = RAPIDJSON_CLZLL(high); + uint32_t lz = internal::clzll(high); length = 8 + (lz >> 3); escaped = true; } } else { - uint32_t lz = RAPIDJSON_CLZLL(low); + uint32_t lz = internal::clzll(low); length = lz >> 3; escaped = true; } @@ -1381,12 +1381,12 @@ class GenericReader { if (low == 0) { if (high != 0) { - uint32_t lz = RAPIDJSON_CLZLL(high); + uint32_t lz = internal::clzll(high); p += 8 + (lz >> 3); break; } } else { - uint32_t lz = RAPIDJSON_CLZLL(low); + uint32_t lz = internal::clzll(low); p += lz >> 3; break; } diff --git a/include/rapidjson/writer.h b/include/rapidjson/writer.h index ce39e76c5..e7fb873a4 100644 --- a/include/rapidjson/writer.h +++ b/include/rapidjson/writer.h @@ -676,12 +676,12 @@ inline bool Writer::ScanWriteUnescapedString(StringStream& is, siz bool escaped = false; if (low == 0) { if (high != 0) { - uint32_t lz = RAPIDJSON_CLZLL(high); + uint32_t lz = internal::clzll(high); len = 8 + (lz >> 3); escaped = true; } } else { - uint32_t lz = RAPIDJSON_CLZLL(low); + uint32_t lz = internal::clzll(low); len = lz >> 3; escaped = true; }