Greetings, This patch adds a lightweight self-consistency check to many vector operations. Google issue 5246356.
Ok for google/integration branch? Thanks, -- 2011-09-06 Paul Pluzhnikov <ppluzhni...@google.com> * include/bits/stl_vector.h (__is_valid): New function. (begin, end, size, capacity, swap, clear): Call it. * include/bits/vector.tcc (operator=): Likewise. Index: include/bits/stl_vector.h =================================================================== --- include/bits/stl_vector.h (revision 178493) +++ include/bits/stl_vector.h (working copy) @@ -234,6 +234,16 @@ using _Base::_M_impl; using _Base::_M_get_Tp_allocator; + bool __is_valid() const + { + return (this->_M_impl._M_end_of_storage == 0 + && this->_M_impl._M_start == 0 + && this->_M_impl._M_finish == 0) + || (this->_M_impl._M_start <= this->_M_impl._M_finish + && this->_M_impl._M_finish <= this->_M_impl._M_end_of_storage + && this->_M_impl._M_start < this->_M_impl._M_end_of_storage); + } + public: // [23.2.4.1] construct/copy/destroy // (assign() and get_allocator() are also listed in this section) @@ -531,7 +541,13 @@ */ iterator begin() _GLIBCXX_NOEXCEPT - { return iterator(this->_M_impl._M_start); } + { +#if __google_stl_debug_dangling_vector + if (!this->__is_valid()) + __throw_logic_error("begin() on corrupt (dangling?) vector"); +#endif + return iterator(this->_M_impl._M_start); + } /** * Returns a read-only (constant) iterator that points to the @@ -540,7 +556,13 @@ */ const_iterator begin() const _GLIBCXX_NOEXCEPT - { return const_iterator(this->_M_impl._M_start); } + { +#if __google_stl_debug_dangling_vector + if (!this->__is_valid()) + __throw_logic_error("begin() on corrupt (dangling?) vector"); +#endif + return const_iterator(this->_M_impl._M_start); + } /** * Returns a read/write iterator that points one past the last @@ -549,7 +571,13 @@ */ iterator end() _GLIBCXX_NOEXCEPT - { return iterator(this->_M_impl._M_finish); } + { +#if __google_stl_debug_dangling_vector + if (!this->__is_valid()) + __throw_logic_error("end() on corrupt (dangling?) vector"); +#endif + return iterator(this->_M_impl._M_finish); + } /** * Returns a read-only (constant) iterator that points one past @@ -558,7 +586,13 @@ */ const_iterator end() const _GLIBCXX_NOEXCEPT - { return const_iterator(this->_M_impl._M_finish); } + { +#if __google_stl_debug_dangling_vector + if (!this->__is_valid()) + __throw_logic_error("end() on corrupt (dangling?) vector"); +#endif + return const_iterator(this->_M_impl._M_finish); + } /** * Returns a read/write reverse iterator that points to the @@ -638,7 +672,13 @@ /** Returns the number of elements in the %vector. */ size_type size() const _GLIBCXX_NOEXCEPT - { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); } + { +#if __google_stl_debug_dangling_vector + if (!this->__is_valid()) + __throw_logic_error("size() on corrupt (dangling?) vector"); +#endif + return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); + } /** Returns the size() of the largest possible %vector. */ size_type @@ -718,7 +758,12 @@ */ size_type capacity() const _GLIBCXX_NOEXCEPT - { return size_type(this->_M_impl._M_end_of_storage + { +#if __google_stl_debug_dangling_vector + if (!this->__is_valid()) + __throw_logic_error("capacity() on corrupt (dangling?) vector"); +#endif + return size_type(this->_M_impl._M_end_of_storage - this->_M_impl._M_start); } /** @@ -1112,6 +1157,10 @@ noexcept(_Alloc_traits::_S_nothrow_swap()) #endif { +#if __google_stl_debug_dangling_vector + if (!this->__is_valid() || !__x.__is_valid()) + __throw_logic_error("swap() on corrupt (dangling?) vector"); +#endif this->_M_impl._M_swap_data(__x._M_impl); _Alloc_traits::_S_on_swap(_M_get_Tp_allocator(), __x._M_get_Tp_allocator()); @@ -1125,7 +1174,13 @@ */ void clear() _GLIBCXX_NOEXCEPT - { _M_erase_at_end(this->_M_impl._M_start); } + { +#if __google_stl_debug_dangling_vector + if (!this->__is_valid()) + __throw_logic_error("clear() on corrupt (dangling?) vector"); +#endif + _M_erase_at_end(this->_M_impl._M_start); + } protected: /** Index: include/bits/vector.tcc =================================================================== --- include/bits/vector.tcc (revision 178493) +++ include/bits/vector.tcc (working copy) @@ -158,6 +158,10 @@ vector<_Tp, _Alloc>:: operator=(const vector<_Tp, _Alloc>& __x) { +#if __google_stl_debug_dangling_vector + if (!this->__is_valid() || !__x.__is_valid()) + __throw_logic_error("operator=() on corrupt (dangling?) vector"); +#endif if (&__x != this) { #ifdef __GXX_EXPERIMENTAL_CXX0X__ -- This patch is available for review at http://codereview.appspot.com/4973065