https://gcc.gnu.org/g:4484945c538b26da6881f83f664235988e471d40
commit r15-5486-g4484945c538b26da6881f83f664235988e471d40 Author: Jonathan Wakely <jwak...@redhat.com> Date: Tue Nov 19 23:38:19 2024 +0000 libstdc++: Fix std::unordered_set::emplace optimization [PR117686] The __is_key_type specialization that matches a pair<key_type, T> argument is intended for std::unordered_map, not for std::unordered_set<std::pair<K,T>>. This uses a pair<const Args&...> as the template argument for __is_key_type, so that it won't match a set's key_type. libstdc++-v3/ChangeLog: PR libstdc++/117686 * include/bits/hashtable.h (_Hashtable::_M_emplace_uniq): Adjust usage of __is_key_type to avoid false positive. * testsuite/23_containers/unordered_set/insert/117686.cc: New test. Diff: --- libstdc++-v3/include/bits/hashtable.h | 4 ++-- .../23_containers/unordered_set/insert/117686.cc | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h index a704816573ae..b8bd8c2f4181 100644 --- a/libstdc++-v3/include/bits/hashtable.h +++ b/libstdc++-v3/include/bits/hashtable.h @@ -2286,9 +2286,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } else if constexpr (sizeof...(_Args) == 2) { - pair<const _Args&...> __refs(__args...); - if constexpr (__is_key_type<pair<_Args...>>) + if constexpr (__is_key_type<pair<const _Args&...>>) { + pair<const _Args&...> __refs(__args...); const auto& __key = _ExtractKey{}(__refs); __kp = std::__addressof(__key); } diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/insert/117686.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/insert/117686.cc new file mode 100644 index 000000000000..3baac16c2b47 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/insert/117686.cc @@ -0,0 +1,16 @@ +// { dg-do compile { target c++11 } } +// Bug 117686 - error in unordered_set::emplace + +#include <unordered_set> +#include <utility> + +struct H { + std::size_t operator()(const std::pair<int, int>&) const { return 0; } +}; + +void +test_117686() +{ + std::unordered_set<std::pair<int, int>, H> s; + s.emplace(1, 2); +}