[libcxx-commits] [libcxx] [libc++] Fix insert() calling incorrect constructors (PR #146231)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Jun 28 11:10:15 PDT 2025
https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/146231
This fixes `insert()` calling the wrong `allocator_traits::construct` in the associative containers by removing the special handling that lead to the inconsistencty inside `__tree`.
>From 5b68b3bfd8f5e74a346210edddab21d4e507249f Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Sat, 28 Jun 2025 20:04:22 +0200
Subject: [PATCH] [libc++] Fix insert() calling incorrect constructors
---
libcxx/include/__tree | 46 +------------------
libcxx/include/map | 28 +++++------
libcxx/include/set | 24 +++++-----
...map_allocator_requirement_test_templates.h | 10 ++--
...set_allocator_requirement_test_templates.h | 2 +-
5 files changed, 34 insertions(+), 76 deletions(-)
diff --git a/libcxx/include/__tree b/libcxx/include/__tree
index 9d4ba3ad0639c..b3c0ece8e5fdb 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -1015,32 +1015,6 @@ public:
return __emplace_hint_unique_key_args(__p, __x.first, std::forward<_Pp>(__x)).first;
}
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __insert_unique(const value_type& __v) {
- return __emplace_unique_key_args(__v, __v);
- }
-
- _LIBCPP_HIDE_FROM_ABI iterator __insert_unique(const_iterator __p, const value_type& __v) {
- return __emplace_hint_unique_key_args(__p, __v, __v).first;
- }
-
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __insert_unique(value_type&& __v) {
- return __emplace_unique_key_args(__v, std::move(__v));
- }
-
- _LIBCPP_HIDE_FROM_ABI iterator __insert_unique(const_iterator __p, value_type&& __v) {
- return __emplace_hint_unique_key_args(__p, __v, std::move(__v)).first;
- }
-
- template <class _Vp, __enable_if_t<!is_same<__remove_const_ref_t<_Vp>, value_type>::value, int> = 0>
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> __insert_unique(_Vp&& __v) {
- return __emplace_unique(std::forward<_Vp>(__v));
- }
-
- template <class _Vp, __enable_if_t<!is_same<__remove_const_ref_t<_Vp>, value_type>::value, int> = 0>
- _LIBCPP_HIDE_FROM_ABI iterator __insert_unique(const_iterator __p, _Vp&& __v) {
- return __emplace_hint_unique(__p, std::forward<_Vp>(__v));
- }
-
template <class _ValueT = _Tp, __enable_if_t<__is_tree_value_type<_ValueT>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI void
__insert_unique_from_orphaned_node(const_iterator __p, __get_node_value_type_t<_Tp>&& __value) {
@@ -1052,22 +1026,6 @@ public:
__emplace_hint_unique(__p, std::move(__value));
}
- _LIBCPP_HIDE_FROM_ABI iterator __insert_multi(value_type&& __v) { return __emplace_multi(std::move(__v)); }
-
- _LIBCPP_HIDE_FROM_ABI iterator __insert_multi(const_iterator __p, value_type&& __v) {
- return __emplace_hint_multi(__p, std::move(__v));
- }
-
- template <class _Vp>
- _LIBCPP_HIDE_FROM_ABI iterator __insert_multi(_Vp&& __v) {
- return __emplace_multi(std::forward<_Vp>(__v));
- }
-
- template <class _Vp>
- _LIBCPP_HIDE_FROM_ABI iterator __insert_multi(const_iterator __p, _Vp&& __v) {
- return __emplace_hint_multi(__p, std::forward<_Vp>(__v));
- }
-
template <class _ValueT = _Tp, __enable_if_t<__is_tree_value_type<_ValueT>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI void __insert_multi_from_orphaned_node(const_iterator __p, value_type&& __value) {
__emplace_hint_multi(__p, const_cast<key_type&&>(__value.first), std::move(__value.second));
@@ -1360,7 +1318,7 @@ void __tree<_Tp, _Compare, _Allocator>::__assign_unique(_ForwardIterator __first
}
}
for (; __first != __last; ++__first)
- __insert_unique(*__first);
+ __emplace_unique(*__first);
}
template <class _Tp, class _Compare, class _Allocator>
@@ -1380,7 +1338,7 @@ void __tree<_Tp, _Compare, _Allocator>::__assign_multi(_InputIterator __first, _
}
const_iterator __e = end();
for (; __first != __last; ++__first)
- __insert_multi(__e, *__first);
+ __emplace_hint_multi(__e, *__first);
}
template <class _Tp, class _Compare, class _Allocator>
diff --git a/libcxx/include/map b/libcxx/include/map
index 6c271392911dc..f441768f2f8e4 100644
--- a/libcxx/include/map
+++ b/libcxx/include/map
@@ -1073,29 +1073,29 @@ public:
template <class _Pp, __enable_if_t<is_constructible<value_type, _Pp>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(_Pp&& __p) {
- return __tree_.__insert_unique(std::forward<_Pp>(__p));
+ return __tree_.__emplace_unique(std::forward<_Pp>(__p));
}
template <class _Pp, __enable_if_t<is_constructible<value_type, _Pp>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __pos, _Pp&& __p) {
- return __tree_.__insert_unique(__pos.__i_, std::forward<_Pp>(__p));
+ return __tree_.__emplace_hint_unique(__pos.__i_, std::forward<_Pp>(__p));
}
# endif // _LIBCPP_CXX03_LANG
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(const value_type& __v) { return __tree_.__insert_unique(__v); }
+ _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(const value_type& __v) { return __tree_.__emplace_unique(__v); }
_LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v) {
- return __tree_.__insert_unique(__p.__i_, __v);
+ return __tree_.__emplace_hint_unique(__p.__i_, __v);
}
# ifndef _LIBCPP_CXX03_LANG
_LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(value_type&& __v) {
- return __tree_.__insert_unique(std::move(__v));
+ return __tree_.__emplace_unique(std::move(__v));
}
_LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v) {
- return __tree_.__insert_unique(__p.__i_, std::move(__v));
+ return __tree_.__emplace_hint_unique(__p.__i_, std::move(__v));
}
_LIBCPP_HIDE_FROM_ABI void insert(initializer_list<value_type> __il) { insert(__il.begin(), __il.end()); }
@@ -1756,34 +1756,34 @@ public:
template <class _Pp, __enable_if_t<is_constructible<value_type, _Pp>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI iterator insert(_Pp&& __p) {
- return __tree_.__insert_multi(std::forward<_Pp>(__p));
+ return __tree_.__emplace_multi(std::forward<_Pp>(__p));
}
template <class _Pp, __enable_if_t<is_constructible<value_type, _Pp>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __pos, _Pp&& __p) {
- return __tree_.__insert_multi(__pos.__i_, std::forward<_Pp>(__p));
+ return __tree_.__emplace_hint_multi(__pos.__i_, std::forward<_Pp>(__p));
}
- _LIBCPP_HIDE_FROM_ABI iterator insert(value_type&& __v) { return __tree_.__insert_multi(std::move(__v)); }
+ _LIBCPP_HIDE_FROM_ABI iterator insert(value_type&& __v) { return __tree_.__emplace_multi(std::move(__v)); }
_LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v) {
- return __tree_.__insert_multi(__p.__i_, std::move(__v));
+ return __tree_.__emplace_hint_multi(__p.__i_, std::move(__v));
}
_LIBCPP_HIDE_FROM_ABI void insert(initializer_list<value_type> __il) { insert(__il.begin(), __il.end()); }
# endif // _LIBCPP_CXX03_LANG
- _LIBCPP_HIDE_FROM_ABI iterator insert(const value_type& __v) { return __tree_.__insert_multi(__v); }
+ _LIBCPP_HIDE_FROM_ABI iterator insert(const value_type& __v) { return __tree_.__emplace_multi(__v); }
_LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v) {
- return __tree_.__insert_multi(__p.__i_, __v);
+ return __tree_.__emplace_hint_multi(__p.__i_, __v);
}
template <class _InputIterator>
_LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __f, _InputIterator __l) {
for (const_iterator __e = cend(); __f != __l; ++__f)
- __tree_.__insert_multi(__e.__i_, *__f);
+ __tree_.__emplace_hint_multi(__e.__i_, *__f);
}
# if _LIBCPP_STD_VER >= 23
@@ -1791,7 +1791,7 @@ public:
_LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {
const_iterator __end = cend();
for (auto&& __element : __range) {
- __tree_.__insert_multi(__end.__i_, std::forward<decltype(__element)>(__element));
+ __tree_.__emplace_hint_multi(__end.__i_, std::forward<decltype(__element)>(__element));
}
}
# endif
diff --git a/libcxx/include/set b/libcxx/include/set
index aeea98adf582b..b4272172de5d7 100644
--- a/libcxx/include/set
+++ b/libcxx/include/set
@@ -740,15 +740,15 @@ public:
}
# endif // _LIBCPP_CXX03_LANG
- _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(const value_type& __v) { return __tree_.__insert_unique(__v); }
+ _LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(const value_type& __v) { return __tree_.__emplace_unique(__v); }
_LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v) {
- return __tree_.__insert_unique(__p, __v);
+ return __tree_.__emplace_hint_unique(__p, __v);
}
template <class _InputIterator>
_LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __f, _InputIterator __l) {
for (const_iterator __e = cend(); __f != __l; ++__f)
- __tree_.__insert_unique(__e, *__f);
+ __tree_.__emplace_hint_unique(__e, *__f);
}
# if _LIBCPP_STD_VER >= 23
@@ -756,18 +756,18 @@ public:
_LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {
const_iterator __end = cend();
for (auto&& __element : __range) {
- __tree_.__insert_unique(__end, std::forward<decltype(__element)>(__element));
+ __tree_.__emplace_hint_unique(__end, std::forward<decltype(__element)>(__element));
}
}
# endif
# ifndef _LIBCPP_CXX03_LANG
_LIBCPP_HIDE_FROM_ABI pair<iterator, bool> insert(value_type&& __v) {
- return __tree_.__insert_unique(std::move(__v));
+ return __tree_.__emplace_unique(std::move(__v));
}
_LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v) {
- return __tree_.__insert_unique(__p, std::move(__v));
+ return __tree_.__emplace_hint_unique(__p, std::move(__v));
}
_LIBCPP_HIDE_FROM_ABI void insert(initializer_list<value_type> __il) { insert(__il.begin(), __il.end()); }
@@ -1209,15 +1209,15 @@ public:
}
# endif // _LIBCPP_CXX03_LANG
- _LIBCPP_HIDE_FROM_ABI iterator insert(const value_type& __v) { return __tree_.__insert_multi(__v); }
+ _LIBCPP_HIDE_FROM_ABI iterator insert(const value_type& __v) { return __tree_.__emplace_multi(__v); }
_LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, const value_type& __v) {
- return __tree_.__insert_multi(__p, __v);
+ return __tree_.__emplace_hint_multi(__p, __v);
}
template <class _InputIterator>
_LIBCPP_HIDE_FROM_ABI void insert(_InputIterator __f, _InputIterator __l) {
for (const_iterator __e = cend(); __f != __l; ++__f)
- __tree_.__insert_multi(__e, *__f);
+ __tree_.__emplace_hint_multi(__e, *__f);
}
# if _LIBCPP_STD_VER >= 23
@@ -1225,16 +1225,16 @@ public:
_LIBCPP_HIDE_FROM_ABI void insert_range(_Range&& __range) {
const_iterator __end = cend();
for (auto&& __element : __range) {
- __tree_.__insert_multi(__end, std::forward<decltype(__element)>(__element));
+ __tree_.__emplace_hint_multi(__end, std::forward<decltype(__element)>(__element));
}
}
# endif
# ifndef _LIBCPP_CXX03_LANG
- _LIBCPP_HIDE_FROM_ABI iterator insert(value_type&& __v) { return __tree_.__insert_multi(std::move(__v)); }
+ _LIBCPP_HIDE_FROM_ABI iterator insert(value_type&& __v) { return __tree_.__emplace_multi(std::move(__v)); }
_LIBCPP_HIDE_FROM_ABI iterator insert(const_iterator __p, value_type&& __v) {
- return __tree_.__insert_multi(__p, std::move(__v));
+ return __tree_.__emplace_hint_multi(__p, std::move(__v));
}
_LIBCPP_HIDE_FROM_ABI void insert(initializer_list<value_type> __il) { insert(__il.begin(), __il.end()); }
diff --git a/libcxx/test/std/containers/map_allocator_requirement_test_templates.h b/libcxx/test/std/containers/map_allocator_requirement_test_templates.h
index 74dc8b15928a9..e37f406a92853 100644
--- a/libcxx/test/std/containers/map_allocator_requirement_test_templates.h
+++ b/libcxx/test/std/containers/map_allocator_requirement_test_templates.h
@@ -50,7 +50,7 @@ void testMapInsert() {
// Testing C::insert(value_type&)
Container c;
ValueTp v(42, 1);
- cc->expect<const ValueTp&>();
+ cc->expect<ValueTp&>();
assert(c.insert(v).second);
assert(!cc->unchecked());
{
@@ -76,7 +76,7 @@ void testMapInsert() {
// Testing C::insert(const value_type&&)
Container c;
const ValueTp v(42, 1);
- cc->expect<const ValueTp&>();
+ cc->expect<const ValueTp&&>();
assert(c.insert(std::move(v)).second);
assert(!cc->unchecked());
{
@@ -139,7 +139,7 @@ void testMapInsert() {
// Testing C::insert(Iter, Iter) for *Iter = value_type&
Container c;
ValueTp ValueList[] = {ValueTp(1, 1), ValueTp(2, 1), ValueTp(3, 1)};
- cc->expect<ValueTp const&>(3);
+ cc->expect<ValueTp&>(3);
c.insert(std::begin(ValueList), std::end(ValueList));
assert(!cc->unchecked());
{
@@ -180,7 +180,7 @@ void testMapInsertHint() {
// Testing C::insert(p, value_type&)
Container c;
ValueTp v(42, 1);
- cc->expect<ValueTp const&>();
+ cc->expect<ValueTp&>();
It ret = c.insert(c.end(), v);
assert(ret != c.end());
assert(c.size() == 1);
@@ -229,7 +229,7 @@ void testMapInsertHint() {
// Testing C::insert(p, const value_type&&)
Container c;
const ValueTp v(42, 1);
- cc->expect<const ValueTp&>();
+ cc->expect<const ValueTp&&>();
It ret = c.insert(c.end(), std::move(v));
assert(ret != c.end());
assert(c.size() == 1);
diff --git a/libcxx/test/std/containers/set_allocator_requirement_test_templates.h b/libcxx/test/std/containers/set_allocator_requirement_test_templates.h
index 9ab5c50e9012e..10552a5b9ee21 100644
--- a/libcxx/test/std/containers/set_allocator_requirement_test_templates.h
+++ b/libcxx/test/std/containers/set_allocator_requirement_test_templates.h
@@ -125,7 +125,7 @@ void testSetInsert() {
// Testing C::insert(Iter, Iter) for *Iter = value_type&"
Container c;
ValueTp ValueList[] = {ValueTp(1), ValueTp(2), ValueTp(3)};
- cc->expect<ValueTp const&>(3);
+ cc->expect<ValueTp&>(3);
c.insert(std::begin(ValueList), std::end(ValueList));
assert(!cc->unchecked());
{
More information about the libcxx-commits
mailing list