[libcxx-commits] [libcxx] Revert "[libc++] Add another const_cast to support hash_map copy assignment" (PR #189427)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Mon Mar 30 11:56:34 PDT 2026


https://github.com/ldionne updated https://github.com/llvm/llvm-project/pull/189427

>From 22209bbb2a75babf4077816954d3a20cc1f08b75 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Mon, 30 Mar 2026 12:35:28 -0400
Subject: [PATCH 1/2] Revert "[libc++] Add another const_cast to support
 hash_map copy assignment"

This reverts commit 5b8c175804821e4f6e5141a7cf2ea8a0f9730834. This commit
was landed without proper review: not by fault of the submitter, but
because I mistakenly thought this was modifying something else entirely
that is unsupported.

See details in #188660.
---
 libcxx/include/__hash_table                      | 16 ++++------------
 .../test/extensions/gnu/hash_map/copy.pass.cpp   |  6 +-----
 2 files changed, 5 insertions(+), 17 deletions(-)

diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table
index 49e2fccfd055a..ef487fb06dd5e 100644
--- a/libcxx/include/__hash_table
+++ b/libcxx/include/__hash_table
@@ -19,7 +19,6 @@
 #include <__cstddef/ptrdiff_t.h>
 #include <__cstddef/size_t.h>
 #include <__functional/hash.h>
-#include <__fwd/pair.h>
 #include <__iterator/iterator_traits.h>
 #include <__math/rounding_functions.h>
 #include <__memory/addressof.h>
@@ -1043,22 +1042,15 @@ private:
 
   _LIBCPP_HIDE_FROM_ABI __next_pointer __detach() _NOEXCEPT;
 
-  template <class _From,
-            class _ValueT                                                                    = _Tp,
-            __enable_if_t<__is_hash_value_type<_ValueT>::value || __is_pair_v<_ValueT>, int> = 0>
+  template <class _From, class _ValueT = _Tp, __enable_if_t<__is_hash_value_type<_ValueT>::value, int> = 0>
   _LIBCPP_HIDE_FROM_ABI void __assign_value(__get_hash_node_value_type_t<_Tp>& __lhs, _From&& __rhs) {
     // This is technically UB, since the object was constructed as `const`.
     // Clang doesn't optimize on this currently though.
-    //
-    // The enable_if check for __is_pair_v is only needed to support
-    // __gnu_cxx::hash_map and may be removed if hash_map is removed.
-    const_cast<__remove_const_t<decltype(__lhs.first)>&>(__lhs.first) = std::forward<_From>(__rhs).first;
-    __lhs.second                                                      = std::forward<_From>(__rhs).second;
+    const_cast<key_type&>(__lhs.first) = const_cast<__copy_cvref_t<_From, key_type>&&>(__rhs.first);
+    __lhs.second                       = std::forward<_From>(__rhs).second;
   }
 
-  template <class _From,
-            class _ValueT                                                                      = _Tp,
-            __enable_if_t<!__is_hash_value_type<_ValueT>::value && !__is_pair_v<_ValueT>, int> = 0>
+  template <class _From, class _ValueT = _Tp, __enable_if_t<!__is_hash_value_type<_ValueT>::value, int> = 0>
   _LIBCPP_HIDE_FROM_ABI void __assign_value(_Tp& __lhs, _From&& __rhs) {
     __lhs = std::forward<_From>(__rhs);
   }
diff --git a/libcxx/test/extensions/gnu/hash_map/copy.pass.cpp b/libcxx/test/extensions/gnu/hash_map/copy.pass.cpp
index ca489e8c1c623..65b8debda0676 100644
--- a/libcxx/test/extensions/gnu/hash_map/copy.pass.cpp
+++ b/libcxx/test/extensions/gnu/hash_map/copy.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// ADDITIONAL_COMPILE_FLAGS: -Wno-deprecated -Wno-deprecated-copy
+// ADDITIONAL_COMPILE_FLAGS: -Wno-deprecated
 
 // hash_map::hash_map(const hash_map&)
 
@@ -23,9 +23,5 @@ int main(int, char**) {
 
   assert(map2.size() == 2);
 
-  map.insert(std::make_pair(3, 1));
-  map2 = map;
-  assert(map2.size() == 3);
-
   return 0;
 }

>From f93d0562f4089743bd985320dfd57ca0413b3fd2 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Mon, 30 Mar 2026 14:55:54 -0400
Subject: [PATCH 2/2] Revert "[libc++] Fix type confusion in hash_{,multi}map"

This reverts commit 30084d74765c70e9cab4f11e9f2c29f141df299e.
---
 libcxx/include/ext/hash_map                    | 18 +++++++++++-------
 .../gnu/hash_map/non_standard_layout.pass.cpp  | 16 ----------------
 .../hash_multimap/non_standard_layout.pass.cpp | 16 ----------------
 3 files changed, 11 insertions(+), 39 deletions(-)
 delete mode 100644 libcxx/test/extensions/gnu/hash_map/non_standard_layout.pass.cpp
 delete mode 100644 libcxx/test/extensions/gnu/hash_multimap/non_standard_layout.pass.cpp

diff --git a/libcxx/include/ext/hash_map b/libcxx/include/ext/hash_map
index 7df44370df96b..09c981131ff96 100644
--- a/libcxx/include/ext/hash_map
+++ b/libcxx/include/ext/hash_map
@@ -426,10 +426,12 @@ public:
   typedef const value_type& const_reference;
 
 private:
-  typedef __hash_map_hasher<value_type, hasher> __hasher;
-  typedef __hash_map_equal<value_type, key_equal> __key_equal;
+  typedef std::pair<key_type, mapped_type> __value_type;
+  typedef __hash_map_hasher<__value_type, hasher> __hasher;
+  typedef __hash_map_equal<__value_type, key_equal> __key_equal;
+  typedef std::__rebind_alloc<std::allocator_traits<allocator_type>, __value_type> __allocator_type;
 
-  typedef std::__hash_table<value_type, __hasher, __key_equal, allocator_type> __table;
+  typedef std::__hash_table<__value_type, __hasher, __key_equal, __allocator_type> __table;
 
   __table __table_;
 
@@ -575,7 +577,7 @@ typename hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__node_holder
 hash_map<_Key, _Tp, _Hash, _Pred, _Alloc>::__construct_node(const key_type& __k) {
   __node_allocator& __na = __table_.__node_alloc();
   __node_holder __h(__node_traits::allocate(__na, 1), _Dp(__na));
-  __node_traits::construct(__na, const_cast<_Key*>(std::addressof(__h->__get_value().first)), __k);
+  __node_traits::construct(__na, std::addressof(__h->__get_value().first), __k);
   __h.get_deleter().__first_constructed = true;
   __node_traits::construct(__na, std::addressof(__h->__get_value().second));
   __h.get_deleter().__second_constructed = true;
@@ -645,10 +647,12 @@ public:
   typedef const value_type& const_reference;
 
 private:
-  typedef __hash_map_hasher<value_type, hasher> __hasher;
-  typedef __hash_map_equal<value_type, key_equal> __key_equal;
+  typedef std::pair<key_type, mapped_type> __value_type;
+  typedef __hash_map_hasher<__value_type, hasher> __hasher;
+  typedef __hash_map_equal<__value_type, key_equal> __key_equal;
+  typedef std::__rebind_alloc<std::allocator_traits<allocator_type>, __value_type> __allocator_type;
 
-  typedef std::__hash_table<value_type, __hasher, __key_equal, allocator_type> __table;
+  typedef std::__hash_table<__value_type, __hasher, __key_equal, __allocator_type> __table;
 
   __table __table_;
 
diff --git a/libcxx/test/extensions/gnu/hash_map/non_standard_layout.pass.cpp b/libcxx/test/extensions/gnu/hash_map/non_standard_layout.pass.cpp
deleted file mode 100644
index 4c8403f5ad744..0000000000000
--- a/libcxx/test/extensions/gnu/hash_map/non_standard_layout.pass.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// ADDITIONAL_COMPILE_FLAGS: -Wno-deprecated
-#include <ext/hash_map>
-
-int main(int, char**) {
-  __gnu_cxx::hash_map<const char*, std::string> m;
-  auto it = m.insert(std::make_pair("foo", "bar")).first;
-  return it->first == nullptr;
-}
diff --git a/libcxx/test/extensions/gnu/hash_multimap/non_standard_layout.pass.cpp b/libcxx/test/extensions/gnu/hash_multimap/non_standard_layout.pass.cpp
deleted file mode 100644
index c8b8a3c63cf52..0000000000000
--- a/libcxx/test/extensions/gnu/hash_multimap/non_standard_layout.pass.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// ADDITIONAL_COMPILE_FLAGS: -Wno-deprecated
-#include <ext/hash_map>
-
-int main(int, char**) {
-  __gnu_cxx::hash_multimap<const char*, std::string> m;
-  auto it = m.insert(std::make_pair("foo", "bar"));
-  return it->first == nullptr;
-}



More information about the libcxx-commits mailing list