[google][4.8] Add more inexpensive debug checks to vector, bitvector, deque

Paul Pluzhnikov ppluzhnikov@google.com
Mon Jan 6 16:46:00 GMT 2014


Greetings,

For Google b/9127283, I've committed attached patch on google/gcc-4_8 branch.

Related: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56109

This caught ~10 bugs for us. erase(end()) and pop_back() on empty
vector appear to be most common.

-- 
Paul Pluzhnikov
-------------- next part --------------
Index: libstdc++-v3/include/bits/stl_vector.h
===================================================================
--- libstdc++-v3/include/bits/stl_vector.h	(revision 206330)
+++ libstdc++-v3/include/bits/stl_vector.h	(working copy)
@@ -1050,6 +1050,10 @@
       void
       pop_back()
       {
+#if __google_stl_debug_vector
+	if (this->empty())
+	  __throw_logic_error(__N("pop_back() on empty vector"));
+#endif
 	--this->_M_impl._M_finish;
 	_Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish);
       }
@@ -1135,7 +1139,13 @@
        */
       void
       insert(iterator __position, size_type __n, const value_type& __x)
-      { _M_fill_insert(__position, __n, __x); }
+      {
+#if __google_stl_debug_vector
+	if (__position < this->begin() || __position > this->end())
+	  __throw_out_of_range(__N("insert() at invalid position"));
+#endif
+	_M_fill_insert(__position, __n, __x);
+      }
 
       /**
        *  @brief  Inserts a range into the %vector.
@@ -1157,13 +1167,23 @@
         void
         insert(iterator __position, _InputIterator __first,
 	       _InputIterator __last)
-        { _M_insert_dispatch(__position, __first, __last, __false_type()); }
+        {
+#if __google_stl_debug_vector
+	  if (__position < this->begin() || __position > this->end())
+	    __throw_out_of_range(__N("insert() at invalid position"));
+#endif
+	  _M_insert_dispatch(__position, __first, __last, __false_type());
+	}
 #else
       template<typename _InputIterator>
         void
         insert(iterator __position, _InputIterator __first,
 	       _InputIterator __last)
         {
+#if __google_stl_debug_vector
+	  if (__position < this->begin() || __position > this->end())
+	    __throw_out_of_range(__N("insert() at invalid position"));
+#endif
 	  // Check whether it's an integral type.  If so, it's not an iterator.
 	  typedef typename std::__is_integer<_InputIterator>::__type _Integral;
 	  _M_insert_dispatch(__position, __first, __last, _Integral());
Index: libstdc++-v3/include/bits/stl_deque.h
===================================================================
--- libstdc++-v3/include/bits/stl_deque.h	(revision 206330)
+++ libstdc++-v3/include/bits/stl_deque.h	(working copy)
@@ -1552,7 +1552,13 @@
        */
       void
       insert(iterator __position, size_type __n, const value_type& __x)
-      { _M_fill_insert(__position, __n, __x); }
+      {
+#if __google_stl_debug_deque
+	if (__position < this->begin() || __position > this->end())
+	  __throw_logic_error("insert() at invalid position");
+#endif
+	_M_fill_insert(__position, __n, __x);
+      }
 
       /**
        *  @brief  Inserts a range into the %deque.
@@ -1570,7 +1576,13 @@
         void
         insert(iterator __position, _InputIterator __first,
 	       _InputIterator __last)
-        { _M_insert_dispatch(__position, __first, __last, __false_type()); }
+        {
+#if __google_stl_debug_deque
+	if (__position < this->begin() || __position > this->end())
+	  __throw_logic_error("insert() at invalid position");
+#endif
+	  _M_insert_dispatch(__position, __first, __last, __false_type());
+	}
 #else
       template<typename _InputIterator>
         void
Index: libstdc++-v3/include/bits/vector.tcc
===================================================================
--- libstdc++-v3/include/bits/vector.tcc	(revision 206330)
+++ libstdc++-v3/include/bits/vector.tcc	(working copy)
@@ -107,6 +107,10 @@
     vector<_Tp, _Alloc>::
     insert(iterator __position, const value_type& __x)
     {
+#if __google_stl_debug_vector
+      if (__position < this->begin() || __position > this->end())
+	__throw_out_of_range(__N("insert() at invalid position"));
+#endif
       const size_type __n = __position - begin();
       if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
 	  && __position == end())
@@ -134,6 +138,10 @@
     vector<_Tp, _Alloc>::
     erase(iterator __position)
     {
+#if __google_stl_debug_vector
+      if (__position < this->begin() || __position >= this->end())
+	__throw_out_of_range(__N("erase() at invalid position"));
+#endif
       if (__position + 1 != end())
 	_GLIBCXX_MOVE3(__position + 1, end(), __position);
       --this->_M_impl._M_finish;
@@ -146,6 +154,10 @@
     vector<_Tp, _Alloc>::
     erase(iterator __first, iterator __last)
     {
+#if __google_stl_debug_vector
+      if (__first < this->begin() || __first > __last || __last > this->end())
+	__throw_out_of_range("erase() invalid range");
+#endif
       if (__first != __last)
 	{
 	  if (__last != end())
@@ -298,6 +310,10 @@
       vector<_Tp, _Alloc>::
       emplace(iterator __position, _Args&&... __args)
       {
+#if __google_stl_debug_vector
+	if (__position < this->begin() || __position > this->end())
+	  __throw_out_of_range(__N("emplace() at invalid position"));
+#endif
 	const size_type __n = __position - begin();
 	if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
 	    && __position == end())
Index: libstdc++-v3/include/bits/deque.tcc
===================================================================
--- libstdc++-v3/include/bits/deque.tcc	(revision 206330)
+++ libstdc++-v3/include/bits/deque.tcc	(working copy)
@@ -193,6 +193,10 @@
     deque<_Tp, _Alloc>::
     erase(iterator __position)
     {
+#if __google_stl_debug_deque
+      if (__position < this->begin() || __position >= this->end())
+	__throw_logic_error("erase() at invalid position");
+#endif
       iterator __next = __position;
       ++__next;
       const difference_type __index = __position - begin();
@@ -216,6 +220,10 @@
     deque<_Tp, _Alloc>::
     erase(iterator __first, iterator __last)
     {
+#if __google_stl_debug_deque
+      if (__first < this->begin() || __first > __last || __last > this->end())
+	  __throw_logic_error("erase() invalid range");
+#endif
       if (__first == __last)
 	return __first;
       else if (__first == begin() && __last == end())
Index: libstdc++-v3/include/bits/stl_bvector.h
===================================================================
--- libstdc++-v3/include/bits/stl_bvector.h	(revision 206330)
+++ libstdc++-v3/include/bits/stl_bvector.h	(working copy)
@@ -978,6 +978,10 @@
     iterator
     insert(iterator __position, const bool& __x = bool())
     {
+#if __google_stl_debug_bvector
+      if (__position < this->begin() || __position > this->end())
+	__throw_logic_error("insert() at invalid position");
+#endif
       const difference_type __n = __position - begin();
       if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage
 	  && __position == end())
@@ -997,6 +1001,8 @@
 #if __google_stl_debug_bvector
 	if (!this->_M_is_valid())
 	  __throw_logic_error("insert() on corrupt (dangling?) vector");
+	if (__position < this->begin() || __position > this->end())
+	  __throw_logic_error("insert() at invalid position");
 #endif
 	_M_insert_dispatch(__position, __first, __last, __false_type());
       }
@@ -1009,6 +1015,8 @@
 #if __google_stl_debug_bvector
 	if (!this->_M_is_valid())
 	  __throw_logic_error("insert() on corrupt (dangling?) vector");
+	if (__position < this->begin() || __position > this->end())
+	  __throw_logic_error("insert() at invalid position");
 #endif
 	typedef typename std::__is_integer<_InputIterator>::__type _Integral;
 	_M_insert_dispatch(__position, __first, __last, _Integral());
@@ -1021,6 +1029,8 @@
 #if __google_stl_debug_bvector
       if (!this->_M_is_valid())
 	__throw_logic_error("insert() on corrupt (dangling?) vector");
+      if (__position < this->begin() || __position > this->end())
+	__throw_logic_error("insert() at invalid position");
 #endif
       _M_fill_insert(__position, __n, __x);
     }
@@ -1043,7 +1053,8 @@
     erase(iterator __position)
     {
 #if __google_stl_debug_bvector
-      _M_range_check(__position - begin());
+      if (__position < this->begin() || __position >= this->end())
+	__throw_logic_error("erase() at invalid position");
 #endif
       if (__position + 1 != end())
         std::copy(__position + 1, end(), __position);
@@ -1057,6 +1068,8 @@
 #if __google_stl_debug_bvector
       if (!this->_M_is_valid())
 	__throw_logic_error("erase() on corrupt (dangling?) vector");
+      if (__first < this->begin() || __first > __last || __last > this->end())
+	__throw_logic_error("erase() invalid range");
 #endif
       if (__first != __last)
 	_M_erase_at_end(std::copy(__last, end(), __first));
Index: libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
===================================================================
--- libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc	(revision 206330)
+++ libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc	(working copy)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1290 }
+// { dg-error "no matching" "" { target *-*-* } 1310 }
 
 #include <vector>
 #include <utility>
Index: libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
===================================================================
--- libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc	(revision 206330)
+++ libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc	(working copy)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1364 }
+// { dg-error "no matching" "" { target *-*-* } 1384 }
 
 #include <vector>
 
Index: libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
===================================================================
--- libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc	(revision 206330)
+++ libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc	(working copy)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1405 }
+// { dg-error "no matching" "" { target *-*-* } 1425 }
 
 #include <vector>
 
Index: libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
===================================================================
--- libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc	(revision 206330)
+++ libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc	(working copy)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1290 }
+// { dg-error "no matching" "" { target *-*-* } 1310 }
 
 #include <vector>
 
Index: libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc
===================================================================
--- libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc	(revision 206330)
+++ libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc	(working copy)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1666 }
+// { dg-error "no matching" "" { target *-*-* } 1678 }
 
 #include <deque>
 #include <utility>
Index: libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc
===================================================================
--- libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc	(revision 206330)
+++ libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc	(working copy)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1733 }
+// { dg-error "no matching" "" { target *-*-* } 1745 }
 
 #include <deque>
 
Index: libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc
===================================================================
--- libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc	(revision 206330)
+++ libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc	(working copy)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1817 }
+// { dg-error "no matching" "" { target *-*-* } 1829 }
 
 #include <deque>
 
Index: libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc
===================================================================
--- libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc	(revision 206330)
+++ libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc	(working copy)
@@ -18,7 +18,7 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1666 }
+// { dg-error "no matching" "" { target *-*-* } 1678 }
 
 #include <deque>
 


More information about the Gcc-patches mailing list