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
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>
 

Reply via email to