aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-04-15 03:17:26 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-04-15 03:17:26 +0000
commit1d44ed0e6aa4539b759b3dd8e0f4fd44415f6f05 (patch)
tree686ddc9c657ee26a11302901c88f166557189643
parentbbfaa6541bf4c484559fc0e07ba56398e544eded (diff)
parent82bcd7810d919a3abca46e062f27ab93a327a08a (diff)
downloadprotobuf-android14-d1-release.tar.gz
Change-Id: Ie46d1a0f2dba7b88939fc00d289c9c115049a740
-rw-r--r--src/google/protobuf/map.h15
1 files changed, 14 insertions, 1 deletions
diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h
index 008c19225..5634f50bb 100644
--- a/src/google/protobuf/map.h
+++ b/src/google/protobuf/map.h
@@ -331,6 +331,18 @@ size_t SpaceUsedInValues(const Map* map) {
inline size_t SpaceUsedInValues(const void*) { return 0; }
+// Multiply two numbers where overflow is expected.
+template <typename N>
+N MultiplyWithOverflow(N a, N b) {
+#if __has_builtin(__builtin_mul_overflow)
+ N res;
+ (void)__builtin_mul_overflow(a, b, &res);
+ return res;
+#else
+ return a * b;
+#endif
+}
+
} // namespace internal
// This is the class for Map's internal value_type. Instead of using
@@ -1099,7 +1111,8 @@ class Map {
// the hash value. The constant kPhi (suggested by Knuth) is roughly
// (sqrt(5) - 1) / 2 * 2^64.
constexpr uint64_t kPhi = uint64_t{0x9e3779b97f4a7c15};
- return ((kPhi * h) >> 32) & (num_buckets_ - 1);
+ return (internal::MultiplyWithOverflow(kPhi, h) >> 32) &
+ (num_buckets_ - 1);
}
// Return a power of two no less than max(kMinTableSize, n).