Use builtin multiplication for intentional overflow

Clang's unsigned integer overflow sanitizer is flagging BucketNumber as having
an overflow. This is intentional behavior, so we should mark it as such.
Rather than disabling the sanitizer, this uses __builtin_mul_overflow to
indicate the overflow is intentional.

PiperOrigin-RevId: 524018233
pull/12461/head
Protobuf Team Bot 2 years ago committed by Copybara-Service
parent 31f649fb18
commit b9e056f779
  1. 14
      src/google/protobuf/map.h

@ -655,6 +655,18 @@ struct KeyNode : NodeBase {
decltype(auto) key() const { return ReadKey<Key>(GetVoidKey()); }
};
// 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
}
// KeyMapBase is a chaining hash map with the additional feature that some
// buckets can be converted to use an ordered container. This ensures O(lg n)
// bounds on find, insert, and erase, while avoiding the overheads of ordered
@ -1019,7 +1031,7 @@ class KeyMapBase : public UntypedMapBase {
// 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 (MultiplyWithOverflow(kPhi, h) >> 32) & (num_buckets_ - 1);
}
void DestroyTree(Tree* tree) {

Loading…
Cancel
Save