https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120288
Bug ID: 120288 Summary: spurious null pointer dereference in std::__detail::_Hashtable_base::_M_key_equals since gcc-15 Product: gcc Version: 15.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: adl at gnu dot org Target Milestone: --- Created attachment 61428 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=61428&action=edit preprocessed sources The following code produces spurious "potential null pointer dereference" with GCC 15.1 and Debian's gcc-snapshot (20250502). Those false positives where not produced with GCC 14.2 and earlier. I found it quite hard to reduce the problem, because the diagnostics were only pointing to the C++ headers, without any indication of what part of my code called that method. https://godbolt.org/z/s7W46dqnj % cat foo.cc #include <unordered_map> class key { }; bool less_than(const key* left, const key* right) noexcept; struct hash { size_t operator()(const key*) const noexcept { return 0; } }; struct equal { bool operator()(const key* left, const key* right) const noexcept { return less_than(left, right); } }; class foo { public: foo(); private: std::unordered_map<const key*, int, hash, equal> map; }; foo::foo() { key b; map.find(&b); } % g++ -O -Wnull-dereference -Werror -c foo.cc In file included from /usr/lib/gcc-snapshot/include/c++/16/bits/hashtable.h:37, from /usr/lib/gcc-snapshot/include/c++/16/bits/unordered_map.h:33, from /usr/lib/gcc-snapshot/include/c++/16/unordered_map:43, from foo.cc:1: In member function 'bool std::__detail::_Hashtable_base<_Key, _Value, _ExtractKey, _Equal, _Hash, _RangeHash, _Unused, _Traits>::_M_key_equals(const _Key&, const std::__detail::_Hash_node_value<_Value, typename _Traits::__hash_cached::value>&) const [with _Key = const key*; _Value = std::pair<const key* const, int>; _ExtractKey = std::__detail::_Select1st; _Equal = equal; _Hash = hash; _RangeHash = std::__detail::_Mod_range_hashing; _Unused = std::__detail::_Default_ranged_hash; _Traits = std::__detail::_Hashtable_traits<false, false, true>]', inlined from 'std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::__location_type std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::_M_locate(const key_type&) const [with _Key = const key*; _Value = std::pair<const key* const, int>; _Alloc = std::allocator<std::pair<const key* const, int> >; _ExtractKey = std::__detail::_Select1st; _Equal = equal; _Hash = hash; _RangeHash = std::__detail::_Mod_range_hashing; _Unused = std::__detail::_Default_ranged_hash; _RehashPolicy = std::__detail::_Prime_rehash_policy; _Traits = std::__detail::_Hashtable_traits<false, false, true>]' at /usr/lib/gcc-snapshot/include/c++/16/bits/hashtable.h:2272:31, inlined from 'std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::iterator std::_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::find(const key_type&) [with _Key = const key*; _Value = std::pair<const key* const, int>; _Alloc = std::allocator<std::pair<const key* const, int> >; _ExtractKey = std::__detail::_Select1st; _Equal = equal; _Hash = hash; _RangeHash = std::__detail::_Mod_range_hashing; _Unused = std::__detail::_Default_ranged_hash; _RehashPolicy = std::__detail::_Prime_rehash_policy; _Traits = std::__detail::_Hashtable_traits<false, false, true>]' at /usr/lib/gcc-snapshot/include/c++/16/bits/hashtable.h:1918:32: /usr/lib/gcc-snapshot/include/c++/16/bits/hashtable_policy.h:1409:23: error: potential null pointer dereference [-Werror=null-dereference] 1409 | return _M_eq()(__k, _ExtractKey{}(__n._M_v())); | ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cc1plus: all warnings being treated as errors