Fix strict aliasing violation in node_hash_map

node_hash_map uses the function TypeErasedDerefAndApplyToSlotFn to hash a
slot's key. This function accesses a slot pointer as if it were of type
Key* when in fact it is of type value_type* (aka std::pair<const Key,
Value> *). This is technically a strict aliasing violation because the
types of the pointer objects are different.  Fix it by defining a new
type erased function TypeErasedDerefAndApplyToSlotFirstFn that uses the
correct type for the pointer.

PiperOrigin-RevId: 918067685
Change-Id: I5d65e0e077f84a0f869be0e24fee094b4b09fbfb
This commit is contained in:
Peter Collingbourne
2026-05-19 15:45:07 -07:00
committed by Copybara-Service
parent 7153103088
commit 8fb4507d10
2 changed files with 13 additions and 2 deletions

View File

@@ -550,10 +550,20 @@ template <class Fn, class T, bool kIsDefault>
size_t TypeErasedDerefAndApplyToSlotFn(const void* fn, void* slot_ptr,
size_t seed) {
const auto* f = static_cast<const Fn*>(fn);
const T* slot = *static_cast<const T**>(slot_ptr);
const T* slot = *static_cast<T**>(slot_ptr);
return HashElement<Fn, kIsDefault>{*f, seed}(*slot);
}
// Type erased function to apply `Fn` to data inside of the `slot_ptr->first`.
// The data is expected to have type `T`.
template <class Fn, class T, bool kIsDefault>
size_t TypeErasedDerefAndApplyToSlotFirstFn(const void* fn, void* slot_ptr,
size_t seed) {
const auto* f = static_cast<const Fn*>(fn);
const T* slot = *static_cast<T**>(slot_ptr);
return HashElement<Fn, kIsDefault>{*f, seed}(slot->first);
}
} // namespace container_internal
ABSL_NAMESPACE_END
} // namespace absl

View File

@@ -681,7 +681,8 @@ class NodeHashMapPolicy
template <class Hash, bool kIsDefault>
static constexpr HashSlotFn get_hash_slot_fn() {
return memory_internal::IsLayoutCompatible<Key, Value>::value
? &TypeErasedDerefAndApplyToSlotFn<Hash, Key, kIsDefault>
? &TypeErasedDerefAndApplyToSlotFirstFn<Hash, value_type,
kIsDefault>
: nullptr;
}
};