This partially reverts commit 561078480ffb5adb68577276c6b23e4ee7b39272. If we avoid all debug mode checks when erasing elements then we fail to invalidate safe iterators to the removed elements. This reverts the recent changes in r12-4083 and r12-4233, restoring the debug checking.
libstdc++-v3/ChangeLog: * include/experimental/deque (erase, erase_if): Revert changes to avoid debug mode overhead. * include/experimental/map (erase, erase_if): Likewise. * include/experimental/set (erase, erase_if): Likewise. * include/experimental/unordered_map (erase, erase_if): Likewise. * include/experimental/unordered_set (erase, erase_if): Likewise. * include/experimental/vector (erase, erase_if): Likewise. * include/std/deque (erase, erase_if): Likewise. * include/std/map (erase, erase_if): Likewise. * include/std/set (erase, erase_if): Likewise. * include/std/unordered_map (erase, erase_if): Likewise. * include/std/unordered_set (erase, erase_if): Likewise. * include/std/vector (erase, erase_if): Likewise. Tested powerpc64le-linux. Committed to trunk.
commit 82e3a826871effc7093852a9181f641c693ae94f Author: Jonathan Wakely <jwak...@redhat.com> Date: Thu Oct 7 20:33:45 2021 libstdc++: Restore debug checks in uniform container erasure functions This partially reverts commit 561078480ffb5adb68577276c6b23e4ee7b39272. If we avoid all debug mode checks when erasing elements then we fail to invalidate safe iterators to the removed elements. This reverts the recent changes in r12-4083 and r12-4233, restoring the debug checking. libstdc++-v3/ChangeLog: * include/experimental/deque (erase, erase_if): Revert changes to avoid debug mode overhead. * include/experimental/map (erase, erase_if): Likewise. * include/experimental/set (erase, erase_if): Likewise. * include/experimental/unordered_map (erase, erase_if): Likewise. * include/experimental/unordered_set (erase, erase_if): Likewise. * include/experimental/vector (erase, erase_if): Likewise. * include/std/deque (erase, erase_if): Likewise. * include/std/map (erase, erase_if): Likewise. * include/std/set (erase, erase_if): Likewise. * include/std/unordered_map (erase, erase_if): Likewise. * include/std/unordered_set (erase, erase_if): Likewise. * include/std/vector (erase, erase_if): Likewise. diff --git a/libstdc++-v3/include/experimental/deque b/libstdc++-v3/include/experimental/deque index 710833ebcad..a76fb659bbf 100644 --- a/libstdc++-v3/include/experimental/deque +++ b/libstdc++-v3/include/experimental/deque @@ -50,16 +50,16 @@ inline namespace fundamentals_v2 inline void erase_if(deque<_Tp, _Alloc>& __cont, _Predicate __pred) { - _GLIBCXX_STD_C::deque<_Tp, _Alloc>& __c = __cont; - __c.erase(std::remove_if(__c.begin(), __c.end(), __pred), __c.end()); + __cont.erase(std::remove_if(__cont.begin(), __cont.end(), __pred), + __cont.end()); } template<typename _Tp, typename _Alloc, typename _Up> inline void erase(deque<_Tp, _Alloc>& __cont, const _Up& __value) { - _GLIBCXX_STD_C::deque<_Tp, _Alloc>& __c = __cont; - __c.erase(std::remove(__c.begin(), __c.end(), __value), __c.end()); + __cont.erase(std::remove(__cont.begin(), __cont.end(), __value), + __cont.end()); } namespace pmr { diff --git a/libstdc++-v3/include/experimental/map b/libstdc++-v3/include/experimental/map index ef69fadf944..0c0f42222f5 100644 --- a/libstdc++-v3/include/experimental/map +++ b/libstdc++-v3/include/experimental/map @@ -50,19 +50,13 @@ inline namespace fundamentals_v2 typename _Predicate> inline void erase_if(map<_Key, _Tp, _Compare, _Alloc>& __cont, _Predicate __pred) - { - _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Alloc>& __c = __cont; - std::__detail::__erase_nodes_if(__c, __pred); - } + { std::__detail::__erase_nodes_if(__cont, __pred); } template<typename _Key, typename _Tp, typename _Compare, typename _Alloc, typename _Predicate> inline void erase_if(multimap<_Key, _Tp, _Compare, _Alloc>& __cont, _Predicate __pred) - { - _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Alloc>& __c = __cont; - std::__detail::__erase_nodes_if(__c, __pred); - } + { std::__detail::__erase_nodes_if(__cont, __pred); } namespace pmr { template<typename _Key, typename _Tp, typename _Compare = less<_Key>> diff --git a/libstdc++-v3/include/experimental/set b/libstdc++-v3/include/experimental/set index 7a5986aec0e..c3f5433e995 100644 --- a/libstdc++-v3/include/experimental/set +++ b/libstdc++-v3/include/experimental/set @@ -50,19 +50,13 @@ inline namespace fundamentals_v2 typename _Predicate> inline void erase_if(set<_Key, _Compare, _Alloc>& __cont, _Predicate __pred) - { - _GLIBCXX_STD_C::set<_Key, _Compare, _Alloc>& __c = __cont; - std::__detail::__erase_nodes_if(__c, __pred); - } + { std::__detail::__erase_nodes_if(__cont, __pred); } template<typename _Key, typename _Compare, typename _Alloc, typename _Predicate> inline void erase_if(multiset<_Key, _Compare, _Alloc>& __cont, _Predicate __pred) - { - _GLIBCXX_STD_C::multiset<_Key, _Compare, _Alloc>& __c = __cont; - std::__detail::__erase_nodes_if(__c, __pred); - } + { std::__detail::__erase_nodes_if(__cont, __pred); } namespace pmr { template<typename _Key, typename _Compare = less<_Key>> diff --git a/libstdc++-v3/include/experimental/unordered_map b/libstdc++-v3/include/experimental/unordered_map index eba989713fa..0b915ab13e5 100644 --- a/libstdc++-v3/include/experimental/unordered_map +++ b/libstdc++-v3/include/experimental/unordered_map @@ -51,22 +51,14 @@ inline namespace fundamentals_v2 inline void erase_if(unordered_map<_Key, _Tp, _Hash, _CPred, _Alloc>& __cont, _Predicate __pred) - { - _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _CPred, _Alloc>& __c - = __cont; - std::__detail::__erase_nodes_if(__c, __pred); - } + { std::__detail::__erase_nodes_if(__cont, __pred); } template<typename _Key, typename _Tp, typename _Hash, typename _CPred, typename _Alloc, typename _Predicate> inline void erase_if(unordered_multimap<_Key, _Tp, _Hash, _CPred, _Alloc>& __cont, _Predicate __pred) - { - _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash, _CPred, _Alloc>& __c - = __cont; - std::__detail::__erase_nodes_if(__c, __pred); - } + { std::__detail::__erase_nodes_if(__cont, __pred); } namespace pmr { template<typename _Key, typename _Tp, typename _Hash = hash<_Key>, diff --git a/libstdc++-v3/include/experimental/unordered_set b/libstdc++-v3/include/experimental/unordered_set index bc5cc11419e..87db4464401 100644 --- a/libstdc++-v3/include/experimental/unordered_set +++ b/libstdc++-v3/include/experimental/unordered_set @@ -51,21 +51,14 @@ inline namespace fundamentals_v2 inline void erase_if(unordered_set<_Key, _Hash, _CPred, _Alloc>& __cont, _Predicate __pred) - { - _GLIBCXX_STD_C::unordered_set<_Key, _Hash, _CPred, _Alloc>& __c = __cont; - std::__detail::__erase_nodes_if(__c, __pred); - } + { std::__detail::__erase_nodes_if(__cont, __pred); } template<typename _Key, typename _Hash, typename _CPred, typename _Alloc, typename _Predicate> inline void erase_if(unordered_multiset<_Key, _Hash, _CPred, _Alloc>& __cont, _Predicate __pred) - { - _GLIBCXX_STD_C::unordered_multiset<_Key, _Hash, _CPred, _Alloc>& __c - = __cont; - std::__detail::__erase_nodes_if(__c, __pred); - } + { std::__detail::__erase_nodes_if(__cont, __pred); } namespace pmr { template<typename _Key, typename _Hash = hash<_Key>, diff --git a/libstdc++-v3/include/experimental/vector b/libstdc++-v3/include/experimental/vector index c45a500ef5e..a14aedf3364 100644 --- a/libstdc++-v3/include/experimental/vector +++ b/libstdc++-v3/include/experimental/vector @@ -52,16 +52,16 @@ inline namespace fundamentals_v2 inline void erase_if(vector<_Tp, _Alloc>& __cont, _Predicate __pred) { - _GLIBCXX_STD_C::vector<_Tp, _Alloc>& __c = __cont; - __c.erase(std::remove_if(__c.begin(), __c.end(), __pred), __c.end()); + __cont.erase(std::remove_if(__cont.begin(), __cont.end(), __pred), + __cont.end()); } template<typename _Tp, typename _Alloc, typename _Up> inline void erase(vector<_Tp, _Alloc>& __cont, const _Up& __value) { - _GLIBCXX_STD_C::vector<_Tp, _Alloc>& __c = __cont; - __c.erase(std::remove(__c.begin(), __c.end(), __value), __c.end()); + __cont.erase(std::remove(__cont.begin(), __cont.end(), __value), + __cont.end()); } namespace pmr { diff --git a/libstdc++-v3/include/std/deque b/libstdc++-v3/include/std/deque index 71993e757a5..473479c44ac 100644 --- a/libstdc++-v3/include/std/deque +++ b/libstdc++-v3/include/std/deque @@ -95,28 +95,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline typename deque<_Tp, _Alloc>::size_type erase_if(deque<_Tp, _Alloc>& __cont, _Predicate __pred) { - _GLIBCXX_STD_C::deque<_Tp, _Alloc>& __c = __cont; using namespace __gnu_cxx; - const auto __osz = __c.size(); - const auto __end = __c.end(); - auto __removed = std::__remove_if(__c.begin(), __end, + const auto __osz = __cont.size(); + const auto __end = __cont.end(); + auto __removed = std::__remove_if(__cont.begin(), __end, __ops::__pred_iter(std::ref(__pred))); - __c.erase(__removed, __end); - return __osz - __c.size(); + __cont.erase(__removed, __end); + return __osz - __cont.size(); } template<typename _Tp, typename _Alloc, typename _Up> inline typename deque<_Tp, _Alloc>::size_type erase(deque<_Tp, _Alloc>& __cont, const _Up& __value) { - _GLIBCXX_STD_C::deque<_Tp, _Alloc>& __c = __cont; using namespace __gnu_cxx; - const auto __osz = __c.size(); - const auto __end = __c.end(); - auto __removed = std::__remove_if(__c.begin(), __end, + const auto __osz = __cont.size(); + const auto __end = __cont.end(); + auto __removed = std::__remove_if(__cont.begin(), __end, __ops::__iter_equals_val(__value)); - __c.erase(__removed, __end); - return __osz - __c.size(); + __cont.erase(__removed, __end); + return __osz - __cont.size(); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/include/std/map b/libstdc++-v3/include/std/map index 29265580995..44bd44b5922 100644 --- a/libstdc++-v3/include/std/map +++ b/libstdc++-v3/include/std/map @@ -95,19 +95,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename _Predicate> inline typename map<_Key, _Tp, _Compare, _Alloc>::size_type erase_if(map<_Key, _Tp, _Compare, _Alloc>& __cont, _Predicate __pred) - { - _GLIBCXX_STD_C::map<_Key, _Tp, _Compare, _Alloc>& __c = __cont; - return __detail::__erase_nodes_if(__c, __pred); - } + { return __detail::__erase_nodes_if(__cont, __pred); } template<typename _Key, typename _Tp, typename _Compare, typename _Alloc, typename _Predicate> inline typename multimap<_Key, _Tp, _Compare, _Alloc>::size_type erase_if(multimap<_Key, _Tp, _Compare, _Alloc>& __cont, _Predicate __pred) - { - _GLIBCXX_STD_C::multimap<_Key, _Tp, _Compare, _Alloc>& __c = __cont; - return __detail::__erase_nodes_if(__c, __pred); - } + { return __detail::__erase_nodes_if(__cont, __pred); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++20 diff --git a/libstdc++-v3/include/std/set b/libstdc++-v3/include/std/set index 24e6e633624..f1e1864937a 100644 --- a/libstdc++-v3/include/std/set +++ b/libstdc++-v3/include/std/set @@ -91,19 +91,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename _Predicate> inline typename set<_Key, _Compare, _Alloc>::size_type erase_if(set<_Key, _Compare, _Alloc>& __cont, _Predicate __pred) - { - _GLIBCXX_STD_C::set<_Key, _Compare, _Alloc>& __c = __cont; - return __detail::__erase_nodes_if(__c, __pred); - } + { return __detail::__erase_nodes_if(__cont, __pred); } template<typename _Key, typename _Compare, typename _Alloc, typename _Predicate> inline typename multiset<_Key, _Compare, _Alloc>::size_type erase_if(multiset<_Key, _Compare, _Alloc>& __cont, _Predicate __pred) - { - _GLIBCXX_STD_C::multiset<_Key, _Compare, _Alloc>& __c = __cont; - return __detail::__erase_nodes_if(__c, __pred); - } + { return __detail::__erase_nodes_if(__cont, __pred); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++20 diff --git a/libstdc++-v3/include/std/unordered_map b/libstdc++-v3/include/std/unordered_map index 774c21fc28b..e6715069362 100644 --- a/libstdc++-v3/include/std/unordered_map +++ b/libstdc++-v3/include/std/unordered_map @@ -83,11 +83,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline typename unordered_map<_Key, _Tp, _Hash, _CPred, _Alloc>::size_type erase_if(unordered_map<_Key, _Tp, _Hash, _CPred, _Alloc>& __cont, _Predicate __pred) - { - _GLIBCXX_STD_C::unordered_map<_Key, _Tp, _Hash, _CPred, _Alloc>& __c - = __cont; - return __detail::__erase_nodes_if(__c, __pred); - } + { return __detail::__erase_nodes_if(__cont, __pred); } template<typename _Key, typename _Tp, typename _Hash, typename _CPred, typename _Alloc, typename _Predicate> @@ -95,11 +91,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION size_type erase_if(unordered_multimap<_Key, _Tp, _Hash, _CPred, _Alloc>& __cont, _Predicate __pred) - { - _GLIBCXX_STD_C::unordered_multimap<_Key, _Tp, _Hash, _CPred, _Alloc>& __c - = __cont; - return __detail::__erase_nodes_if(__c, __pred); - } + { return __detail::__erase_nodes_if(__cont, __pred); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++20 diff --git a/libstdc++-v3/include/std/unordered_set b/libstdc++-v3/include/std/unordered_set index 3859eeaebd0..1ad93d0031b 100644 --- a/libstdc++-v3/include/std/unordered_set +++ b/libstdc++-v3/include/std/unordered_set @@ -83,21 +83,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline typename unordered_set<_Key, _Hash, _CPred, _Alloc>::size_type erase_if(unordered_set<_Key, _Hash, _CPred, _Alloc>& __cont, _Predicate __pred) - { - _GLIBCXX_STD_C::unordered_set<_Key, _Hash, _CPred, _Alloc>& __c = __cont; - return __detail::__erase_nodes_if(__c, __pred); - } + { return __detail::__erase_nodes_if(__cont, __pred); } template<typename _Key, typename _Hash, typename _CPred, typename _Alloc, typename _Predicate> inline typename unordered_multiset<_Key, _Hash, _CPred, _Alloc>::size_type erase_if(unordered_multiset<_Key, _Hash, _CPred, _Alloc>& __cont, _Predicate __pred) - { - _GLIBCXX_STD_C::unordered_multiset<_Key, _Hash, _CPred, _Alloc>& __c - = __cont; - return __detail::__erase_nodes_if(__c, __pred); - } + { return __detail::__erase_nodes_if(__cont, __pred); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++20 diff --git a/libstdc++-v3/include/std/vector b/libstdc++-v3/include/std/vector index 835fa8aeb69..096511c05b2 100644 --- a/libstdc++-v3/include/std/vector +++ b/libstdc++-v3/include/std/vector @@ -105,28 +105,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline typename vector<_Tp, _Alloc>::size_type erase_if(vector<_Tp, _Alloc>& __cont, _Predicate __pred) { - _GLIBCXX_STD_C::vector<_Tp, _Alloc>& __c = __cont; using namespace __gnu_cxx; - const auto __osz = __c.size(); - const auto __end = __c.end(); - auto __removed(std::__remove_if(__c.begin(), __end, - __ops::__pred_iter(std::ref(__pred)))); - __c.erase(__removed, __end); - return __osz - __c.size(); + const auto __osz = __cont.size(); + const auto __end = __cont.end(); + auto __removed = std::__remove_if(__cont.begin(), __end, + __ops::__pred_iter(std::ref(__pred))); + __cont.erase(__removed, __end); + return __osz - __cont.size(); } template<typename _Tp, typename _Alloc, typename _Up> inline typename vector<_Tp, _Alloc>::size_type erase(vector<_Tp, _Alloc>& __cont, const _Up& __value) { - _GLIBCXX_STD_C::vector<_Tp, _Alloc>& __c = __cont; using namespace __gnu_cxx; - const auto __osz = __c.size(); - const auto __end = __c.end(); - auto __removed = std::__remove_if(__c.begin(), __end, + const auto __osz = __cont.size(); + const auto __end = __cont.end(); + auto __removed = std::__remove_if(__cont.begin(), __end, __ops::__iter_equals_val(__value)); - __c.erase(__removed, __end); - return __osz - __c.size(); + __cont.erase(__removed, __end); + return __osz - __cont.size(); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std