diff mbox series

[committed] libstdc++: Restore debug checks in uniform container erasure functions

Message ID YWApq8a1UNgfgr/O@redhat.com
State New
Headers show
Series [committed] libstdc++: Restore debug checks in uniform container erasure functions | expand

Commit Message

Jonathan Wakely Oct. 8, 2021, 11:21 a.m. UTC
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 <jwakely@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 mbox series

Patch

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