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);
+}

Reply via email to