diff options
-rw-r--r-- | absl/hash/internal/hash.h | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h index 300c63af..e97cb315 100644 --- a/absl/hash/internal/hash.h +++ b/absl/hash/internal/hash.h @@ -409,9 +409,23 @@ AbslHashValue(H hash_state, LongDouble value) { return H::combine(std::move(hash_state), category); } +// Without this overload, an array decays to a pointer and we hash that, which +// is not likely to be what the caller intended. +template <typename H, typename T, size_t N> +H AbslHashValue(H hash_state, T (&)[N]) { + static_assert( + sizeof(T) == -1, + "Hashing C arrays is not allowed. For string literals, wrap the literal " + "in absl::string_view(). To hash the array contents, use " + "absl::MakeSpan() or make the array an std::array. To hash the array " + "address, use &array[0]."); + return hash_state; +} + // AbslHashValue() for hashing pointers template <typename H, typename T> -H AbslHashValue(H hash_state, T* ptr) { +std::enable_if_t<std::is_pointer<T>::value, H> AbslHashValue(H hash_state, + T ptr) { auto v = reinterpret_cast<uintptr_t>(ptr); // Due to alignment, pointers tend to have low bits as zero, and the next few // bits follow a pattern since they are also multiples of some base value. |