Skip to content

Commit 814bb27

Browse files
authored
Replace RAPIDJSON_CLZLL with internal clzll (Tencent#1660)
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 <[email protected]> Co-authored-by: Jun He <[email protected]>
1 parent 563fe5b commit 814bb27

File tree

4 files changed

+18
-19
lines changed

4 files changed

+18
-19
lines changed

include/rapidjson/internal/clzll.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,6 @@
2929
RAPIDJSON_NAMESPACE_BEGIN
3030
namespace internal {
3131

32-
#if (defined(__GNUC__) && __GNUC__ >= 4) || RAPIDJSON_HAS_BUILTIN(__builtin_clzll)
33-
#define RAPIDJSON_CLZLL __builtin_clzll
34-
#else
35-
3632
inline uint32_t clzll(uint64_t x) {
3733
// Passing 0 to __builtin_clzll is UB in GCC and results in an
3834
// infinite loop in the software implementation.
@@ -52,7 +48,11 @@ inline uint32_t clzll(uint64_t x) {
5248
#endif // _WIN64
5349

5450
return 63 - r;
51+
#elif (defined(__GNUC__) && __GNUC__ >= 4) || RAPIDJSON_HAS_BUILTIN(__builtin_clzll)
52+
// __builtin_clzll wrapper
53+
return static_cast<uint32_t>(__builtin_clzll(x));
5554
#else
55+
// naive version
5656
uint32_t r;
5757
while (!(x & (static_cast<uint64_t>(1) << 63))) {
5858
x <<= 1;
@@ -64,9 +64,8 @@ inline uint32_t clzll(uint64_t x) {
6464
}
6565

6666
#define RAPIDJSON_CLZLL RAPIDJSON_NAMESPACE::internal::clzll
67-
#endif // (defined(__GNUC__) && __GNUC__ >= 4) || RAPIDJSON_HAS_BUILTIN(__builtin_clzll)
6867

6968
} // namespace internal
7069
RAPIDJSON_NAMESPACE_END
7170

72-
#endif // RAPIDJSON_CLZLL_H_
71+
#endif // RAPIDJSON_CLZLL_H_

include/rapidjson/internal/diyfp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ struct DiyFp {
100100
}
101101

102102
DiyFp Normalize() const {
103-
int s = static_cast<int>(RAPIDJSON_CLZLL(f));
103+
int s = static_cast<int>(clzll(f));
104104
return DiyFp(f << s, e - s);
105105
}
106106

include/rapidjson/reader.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -450,11 +450,11 @@ inline const char *SkipWhitespace_SIMD(const char* p) {
450450

451451
if (low == 0) {
452452
if (high != 0) {
453-
uint32_t lz = RAPIDJSON_CLZLL(high);
453+
uint32_t lz = internal::clzll(high);
454454
return p + 8 + (lz >> 3);
455455
}
456456
} else {
457-
uint32_t lz = RAPIDJSON_CLZLL(low);
457+
uint32_t lz = internal::clzll(low);
458458
return p + (lz >> 3);
459459
}
460460
}
@@ -486,11 +486,11 @@ inline const char *SkipWhitespace_SIMD(const char* p, const char* end) {
486486

487487
if (low == 0) {
488488
if (high != 0) {
489-
uint32_t lz = RAPIDJSON_CLZLL(high);
489+
uint32_t lz = internal::clzll(high);
490490
return p + 8 + (lz >> 3);
491491
}
492492
} else {
493-
uint32_t lz = RAPIDJSON_CLZLL(low);
493+
uint32_t lz = internal::clzll(low);
494494
return p + (lz >> 3);
495495
}
496496
}
@@ -1257,12 +1257,12 @@ class GenericReader {
12571257
bool escaped = false;
12581258
if (low == 0) {
12591259
if (high != 0) {
1260-
uint32_t lz = RAPIDJSON_CLZLL(high);
1260+
uint32_t lz = internal::clzll(high);
12611261
length = 8 + (lz >> 3);
12621262
escaped = true;
12631263
}
12641264
} else {
1265-
uint32_t lz = RAPIDJSON_CLZLL(low);
1265+
uint32_t lz = internal::clzll(low);
12661266
length = lz >> 3;
12671267
escaped = true;
12681268
}
@@ -1327,12 +1327,12 @@ class GenericReader {
13271327
bool escaped = false;
13281328
if (low == 0) {
13291329
if (high != 0) {
1330-
uint32_t lz = RAPIDJSON_CLZLL(high);
1330+
uint32_t lz = internal::clzll(high);
13311331
length = 8 + (lz >> 3);
13321332
escaped = true;
13331333
}
13341334
} else {
1335-
uint32_t lz = RAPIDJSON_CLZLL(low);
1335+
uint32_t lz = internal::clzll(low);
13361336
length = lz >> 3;
13371337
escaped = true;
13381338
}
@@ -1381,12 +1381,12 @@ class GenericReader {
13811381

13821382
if (low == 0) {
13831383
if (high != 0) {
1384-
uint32_t lz = RAPIDJSON_CLZLL(high);
1384+
uint32_t lz = internal::clzll(high);
13851385
p += 8 + (lz >> 3);
13861386
break;
13871387
}
13881388
} else {
1389-
uint32_t lz = RAPIDJSON_CLZLL(low);
1389+
uint32_t lz = internal::clzll(low);
13901390
p += lz >> 3;
13911391
break;
13921392
}

include/rapidjson/writer.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -676,12 +676,12 @@ inline bool Writer<StringBuffer>::ScanWriteUnescapedString(StringStream& is, siz
676676
bool escaped = false;
677677
if (low == 0) {
678678
if (high != 0) {
679-
uint32_t lz = RAPIDJSON_CLZLL(high);
679+
uint32_t lz = internal::clzll(high);
680680
len = 8 + (lz >> 3);
681681
escaped = true;
682682
}
683683
} else {
684-
uint32_t lz = RAPIDJSON_CLZLL(low);
684+
uint32_t lz = internal::clzll(low);
685685
len = lz >> 3;
686686
escaped = true;
687687
}

0 commit comments

Comments
 (0)