From 4484945c538b26da6881f83f664235988e471d40 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Tue, 19 Nov 2024 23:38:19 +0000 Subject: [PATCH] libstdc++: Fix std::unordered_set::emplace optimization [PR117686] The __is_key_type specialization that matches a pair argument is intended for std::unordered_map, not for std::unordered_set>. This uses a pair 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. --- libstdc++-v3/include/bits/hashtable.h | 4 ++-- .../23_containers/unordered_set/insert/117686.cc | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 libstdc++-v3/testsuite/23_containers/unordered_set/insert/117686.cc diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h index a704816573a..b8bd8c2f418 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 __refs(__args...); - if constexpr (__is_key_type>) + if constexpr (__is_key_type>) { + pair __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 00000000000..3baac16c2b4 --- /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 +#include + +struct H { + std::size_t operator()(const std::pair&) const { return 0; } +}; + +void +test_117686() +{ + std::unordered_set, H> s; + s.emplace(1, 2); +}