[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