+cc libstd...@gcc.gnu.org On Thu, May 23, 2013 at 8:51 AM, Paul Pluzhnikov <ppluzhni...@google.com> wrote: > Greetings, > > This patch adds (relatively) cheap bounds and dangling checks to > vector<bool>, similar to the checks I added to vector<T> in r195373, > r195356, etc. > > Ok for google branches (gcc-4_7, gcc-4_8, integration) ? > > Thanks,
-- Paul Pluzhnikov
Index: libstdc++-v3/include/bits/stl_bvector.h =================================================================== --- libstdc++-v3/include/bits/stl_bvector.h (revision 199261) +++ libstdc++-v3/include/bits/stl_bvector.h (working copy) @@ -438,11 +438,31 @@ #endif ~_Bvector_base() - { this->_M_deallocate(); } + { + this->_M_deallocate(); +#if __google_stl_debug_bvector + __builtin_memset(this, 0xcd, sizeof(*this)); +#endif + } protected: _Bvector_impl _M_impl; +#if __google_stl_debug_bvector + bool _M_is_valid() const + { + return (this->_M_impl._M_start._M_p == 0 + && this->_M_impl._M_finish._M_p == 0 + && this->_M_impl._M_end_of_storage == 0) + || (this->_M_impl._M_start._M_p <= this->_M_impl._M_finish._M_p + && this->_M_impl._M_finish._M_p <= this->_M_impl._M_end_of_storage + && (this->_M_impl._M_start._M_p < this->_M_impl._M_end_of_storage + || (this->_M_impl._M_start._M_p == this->_M_impl._M_end_of_storage + && this->_M_impl._M_start._M_offset == 0 + && this->_M_impl._M_finish._M_offset == 0))); + } +#endif + _Bit_type* _M_allocate(size_t __n) { return _M_impl.allocate(_S_nword(__n)); } @@ -571,6 +591,10 @@ vector& operator=(const vector& __x) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("op=() on corrupt (dangling?) vector"); +#endif if (&__x == this) return *this; if (__x.size() > capacity()) @@ -587,6 +611,10 @@ vector& operator=(vector&& __x) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("op=() on corrupt (dangling?) vector"); +#endif // NB: DR 1204. // NB: DR 675. this->clear(); @@ -608,12 +636,22 @@ // or not the type is an integer. void assign(size_type __n, const bool& __x) - { _M_fill_assign(__n, __x); } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("assign on corrupt (dangling?) vector"); +#endif + _M_fill_assign(__n, __x); + } template<typename _InputIterator> void assign(_InputIterator __first, _InputIterator __last) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("assign() on corrupt (dangling?) vector"); +#endif typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_assign_dispatch(__first, __last, _Integral()); } @@ -626,19 +664,43 @@ iterator begin() _GLIBCXX_NOEXCEPT - { return this->_M_impl._M_start; } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("begin() on corrupt (dangling?) vector"); +#endif + return this->_M_impl._M_start; + } const_iterator begin() const _GLIBCXX_NOEXCEPT - { return this->_M_impl._M_start; } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("begin() on corrupt (dangling?) vector"); +#endif + return this->_M_impl._M_start; + } iterator end() _GLIBCXX_NOEXCEPT - { return this->_M_impl._M_finish; } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("end() on corrupt (dangling?) vector"); +#endif + return this->_M_impl._M_finish; + } const_iterator end() const _GLIBCXX_NOEXCEPT - { return this->_M_impl._M_finish; } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("end() on corrupt (dangling?) vector"); +#endif + return this->_M_impl._M_finish; + } reverse_iterator rbegin() _GLIBCXX_NOEXCEPT @@ -659,11 +721,23 @@ #ifdef __GXX_EXPERIMENTAL_CXX0X__ const_iterator cbegin() const noexcept - { return this->_M_impl._M_start; } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("cbegin() on corrupt (dangling?) vector"); +#endif + return this->_M_impl._M_start; + } const_iterator cend() const noexcept - { return this->_M_impl._M_finish; } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("cend() on corrupt (dangling?) vector"); +#endif + return this->_M_impl._M_finish; + } const_reverse_iterator crbegin() const noexcept @@ -681,6 +755,10 @@ size_type max_size() const _GLIBCXX_NOEXCEPT { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("max_size() on corrupt (dangling?) vector"); +#endif const size_type __isize = __gnu_cxx::__numeric_traits<difference_type>::__max - int(_S_word_bit) + 1; @@ -701,6 +779,9 @@ reference operator[](size_type __n) { +#if __google_stl_debug_bvector + _M_range_check(__n); +#endif return *iterator(this->_M_impl._M_start._M_p + __n / int(_S_word_bit), __n % int(_S_word_bit)); } @@ -708,6 +789,9 @@ const_reference operator[](size_type __n) const { +#if __google_stl_debug_bvector + _M_range_check(__n); +#endif return *const_iterator(this->_M_impl._M_start._M_p + __n / int(_S_word_bit), __n % int(_S_word_bit)); } @@ -740,19 +824,39 @@ reference front() - { return *begin(); } + { +#if __google_stl_debug_bvector + _M_range_check(0); +#endif + return *begin(); + } const_reference front() const - { return *begin(); } + { +#if __google_stl_debug_bvector + _M_range_check(0); +#endif + return *begin(); + } reference back() - { return *(end() - 1); } + { +#if __google_stl_debug_bvector + _M_range_check(0); +#endif + return *(end() - 1); + } const_reference back() const - { return *(end() - 1); } + { +#if __google_stl_debug_bvector + _M_range_check(0); +#endif + return *(end() - 1); + } // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 464. Suggestion for new member functions in standard containers. @@ -765,6 +869,10 @@ void push_back(bool __x) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("push_back() on corrupt (dangling?) vector"); +#endif if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) *this->_M_impl._M_finish++ = __x; else @@ -774,6 +882,10 @@ void swap(vector& __x) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid() || !__x._M_is_valid()) + __throw_logic_error("swap() on corrupt (dangling?) vector"); +#endif std::swap(this->_M_impl._M_start, __x._M_impl._M_start); std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); std::swap(this->_M_impl._M_end_of_storage, @@ -811,26 +923,50 @@ insert(iterator __position, _InputIterator __first, _InputIterator __last) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("insert() on corrupt (dangling?) vector"); +#endif typedef typename std::__is_integer<_InputIterator>::__type _Integral; _M_insert_dispatch(__position, __first, __last, _Integral()); } void insert(iterator __position, size_type __n, const bool& __x) - { _M_fill_insert(__position, __n, __x); } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("insert() on corrupt (dangling?) vector"); +#endif + _M_fill_insert(__position, __n, __x); + } #ifdef __GXX_EXPERIMENTAL_CXX0X__ void insert(iterator __p, initializer_list<bool> __l) - { this->insert(__p, __l.begin(), __l.end()); } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("insert() on corrupt (dangling?) vector"); #endif + this->insert(__p, __l.begin(), __l.end()); + } +#endif void pop_back() - { --this->_M_impl._M_finish; } + { +#if __google_stl_debug_bvector + _M_range_check(0); +#endif + --this->_M_impl._M_finish; + } iterator erase(iterator __position) { +#if __google_stl_debug_bvector + _M_range_check(__position - begin()); +#endif if (__position + 1 != end()) std::copy(__position + 1, end(), __position); --this->_M_impl._M_finish; @@ -840,6 +976,10 @@ iterator erase(iterator __first, iterator __last) { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("erase() on corrupt (dangling?) vector"); +#endif if (__first != __last) _M_erase_at_end(std::copy(__last, end(), __first)); return __first; @@ -857,12 +997,22 @@ #ifdef __GXX_EXPERIMENTAL_CXX0X__ void shrink_to_fit() - { _M_shrink_to_fit(); } + { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("shrink_to_fit() on corrupt (dangling?) vector"); #endif + _M_shrink_to_fit(); + } +#endif void flip() _GLIBCXX_NOEXCEPT { +#if __google_stl_debug_bvector + if (!this->_M_is_valid()) + __throw_logic_error("flip() on corrupt (dangling?) vector"); +#endif for (_Bit_type * __p = this->_M_impl._M_start._M_p; __p != this->_M_impl._M_end_of_storage; ++__p) *__p = ~*__p;