From: Paolo Carlini Date: Tue, 22 Nov 2005 14:53:03 +0000 (+0000) Subject: re PR libstdc++/24975 (Aliasing problems inside libstdc++) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d5e07b79f448ea911bda0acb00c57795eb96e7fc;p=gcc.git re PR libstdc++/24975 (Aliasing problems inside libstdc++) 2005-11-22 Paolo Carlini PR libstdc++/24975 * include/bits/stl_set.h (insert(iterator, const value_type&), erase(iterator), erase(iterator, iterator)): Don't break aliasing rules casting to _Rep_iterator&, forward to _Rb_tree facilities. * include/bits/stl_multiset.h (insert(iterator, const value_type&), erase(iterator), erase(iterator, iterator)): Likewise. * include/bits/stl_tree.h (_Rb_tree<>::_M_insert(_Const_Base_ptr, _Const_Base_ptr, const value_type&), insert_unique(const_iterator, const value_type&), insert_equal(const_iterator, const value_type&), erase(const_iterator), erase(const_iterator, const_iterator)): New, _Rb_tree<>::const_iterator counterparts of existing facilities. From-SVN: r107362 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 96652d2b153..8517757ea00 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,17 @@ +2005-11-22 Paolo Carlini + + PR libstdc++/24975 + * include/bits/stl_set.h (insert(iterator, const value_type&), + erase(iterator), erase(iterator, iterator)): Don't break aliasing + rules casting to _Rep_iterator&, forward to _Rb_tree facilities. + * include/bits/stl_multiset.h (insert(iterator, const value_type&), + erase(iterator), erase(iterator, iterator)): Likewise. + * include/bits/stl_tree.h (_Rb_tree<>::_M_insert(_Const_Base_ptr, + _Const_Base_ptr, const value_type&), insert_unique(const_iterator, + const value_type&), insert_equal(const_iterator, const value_type&), + erase(const_iterator), erase(const_iterator, const_iterator)): New, + _Rb_tree<>::const_iterator counterparts of existing facilities. + 2005-11-21 Benjamin Kosnik Ulrich Drepper diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h index 196c4020575..185f51ce989 100644 --- a/libstdc++-v3/include/bits/stl_multiset.h +++ b/libstdc++-v3/include/bits/stl_multiset.h @@ -331,10 +331,7 @@ namespace _GLIBCXX_STD */ iterator insert(iterator __position, const value_type& __x) - { - typedef typename _Rep_type::iterator _Rep_iterator; - return _M_t.insert_equal((_Rep_iterator&)__position, __x); - } + { return _M_t.insert_equal(__position, __x); } /** * @brief A template function that attemps to insert a range of elements. @@ -361,10 +358,7 @@ namespace _GLIBCXX_STD */ void erase(iterator __position) - { - typedef typename _Rep_type::iterator _Rep_iterator; - _M_t.erase((_Rep_iterator&)__position); - } + { _M_t.erase(__position); } /** * @brief Erases elements according to the provided key. @@ -394,10 +388,7 @@ namespace _GLIBCXX_STD */ void erase(iterator __first, iterator __last) - { - typedef typename _Rep_type::iterator _Rep_iterator; - _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); - } + { _M_t.erase(__first, __last); } /** * Erases all elements in a %multiset. Note that this function only diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h index 2a240e19604..1172e509311 100644 --- a/libstdc++-v3/include/bits/stl_set.h +++ b/libstdc++-v3/include/bits/stl_set.h @@ -343,10 +343,7 @@ namespace _GLIBCXX_STD */ iterator insert(iterator __position, const value_type& __x) - { - typedef typename _Rep_type::iterator _Rep_iterator; - return _M_t.insert_unique((_Rep_iterator&)__position, __x); - } + { return _M_t.insert_unique(__position, __x); } /** * @brief A template function that attemps to insert a range of elements. @@ -357,9 +354,9 @@ namespace _GLIBCXX_STD * Complexity similar to that of the range constructor. */ template - void - insert(_InputIterator __first, _InputIterator __last) - { _M_t.insert_unique(__first, __last); } + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t.insert_unique(__first, __last); } /** * @brief Erases an element from a %set. @@ -372,10 +369,7 @@ namespace _GLIBCXX_STD */ void erase(iterator __position) - { - typedef typename _Rep_type::iterator _Rep_iterator; - _M_t.erase((_Rep_iterator&)__position); - } + { _M_t.erase(__position); } /** * @brief Erases elements according to the provided key. @@ -389,7 +383,8 @@ namespace _GLIBCXX_STD * in any way. Managing the pointer is the user's responsibilty. */ size_type - erase(const key_type& __x) { return _M_t.erase(__x); } + erase(const key_type& __x) + { return _M_t.erase(__x); } /** * @brief Erases a [first,last) range of elements from a %set. @@ -404,10 +399,7 @@ namespace _GLIBCXX_STD */ void erase(iterator __first, iterator __last) - { - typedef typename _Rep_type::iterator _Rep_iterator; - _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); - } + { _M_t.erase(__first, __last); } /** * Erases all elements in a %set. Note that this function only erases diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h index 45d27b50b2a..13088ca7555 100644 --- a/libstdc++-v3/include/bits/stl_tree.h +++ b/libstdc++-v3/include/bits/stl_tree.h @@ -539,6 +539,10 @@ namespace std iterator _M_insert(_Base_ptr __x, _Base_ptr __y, const value_type& __v); + const_iterator + _M_insert(_Const_Base_ptr __x, _Const_Base_ptr __y, + const value_type& __v); + _Link_type _M_copy(_Const_Link_type __x, _Link_type __p); @@ -647,9 +651,15 @@ namespace std iterator insert_unique(iterator __position, const value_type& __x); + const_iterator + insert_unique(const_iterator __position, const value_type& __x); + iterator insert_equal(iterator __position, const value_type& __x); + const_iterator + insert_equal(const_iterator __position, const value_type& __x); + template void insert_unique(_InputIterator __first, _InputIterator __last); @@ -661,12 +671,18 @@ namespace std void erase(iterator __position); + void + erase(const_iterator __position); + size_type erase(const key_type& __x); void erase(iterator __first, iterator __last); + void + erase(const_iterator __first, const_iterator __last); + void erase(const key_type* __first, const key_type* __last); @@ -808,6 +824,25 @@ namespace std return iterator(__z); } + template + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_insert(_Const_Base_ptr __x, _Const_Base_ptr __p, const _Val& __v) + { + bool __insert_left = (__x != 0 || __p == _M_end() + || _M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__p))); + + _Link_type __z = _M_create_node(__v); + + _Rb_tree_insert_and_rebalance(__insert_left, __z, + const_cast<_Base_ptr>(__p), + this->_M_impl._M_header); + ++_M_impl._M_node_count; + return const_iterator(__z); + } + template typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator @@ -954,6 +989,63 @@ namespace std return __position; // Equivalent keys. } + template + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + insert_unique(const_iterator __position, const _Val& __v) + { + // end() + if (__position._M_node == _M_end()) + { + if (size() > 0 + && _M_impl._M_key_compare(_S_key(_M_rightmost()), + _KeyOfValue()(__v))) + return _M_insert(0, _M_rightmost(), __v); + else + return const_iterator(insert_unique(__v).first); + } + else if (_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__position._M_node))) + { + // First, try before... + const_iterator __before = __position; + if (__position._M_node == _M_leftmost()) // begin() + return _M_insert(_M_leftmost(), _M_leftmost(), __v); + else if (_M_impl._M_key_compare(_S_key((--__before)._M_node), + _KeyOfValue()(__v))) + { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); + else + return _M_insert(__position._M_node, + __position._M_node, __v); + } + else + return const_iterator(insert_unique(__v).first); + } + else if (_M_impl._M_key_compare(_S_key(__position._M_node), + _KeyOfValue()(__v))) + { + // ... then try after. + const_iterator __after = __position; + if (__position._M_node == _M_rightmost()) + return _M_insert(0, _M_rightmost(), __v); + else if (_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key((++__after)._M_node))) + { + if (_S_right(__position._M_node) == 0) + return _M_insert(0, __position._M_node, __v); + else + return _M_insert(__after._M_node, __after._M_node, __v); + } + else + return const_iterator(insert_unique(__v).first); + } + else + return __position; // Equivalent keys. + } + template typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator @@ -1008,6 +1100,60 @@ namespace std } } + template + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + insert_equal(const_iterator __position, const _Val& __v) + { + // end() + if (__position._M_node == _M_end()) + { + if (size() > 0 + && !_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(_M_rightmost()))) + return _M_insert(0, _M_rightmost(), __v); + else + return const_iterator(insert_equal(__v)); + } + else if (!_M_impl._M_key_compare(_S_key(__position._M_node), + _KeyOfValue()(__v))) + { + // First, try before... + const_iterator __before = __position; + if (__position._M_node == _M_leftmost()) // begin() + return _M_insert(_M_leftmost(), _M_leftmost(), __v); + else if (!_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key((--__before)._M_node))) + { + if (_S_right(__before._M_node) == 0) + return _M_insert(0, __before._M_node, __v); + else + return _M_insert(__position._M_node, + __position._M_node, __v); + } + else + return const_iterator(insert_equal(__v)); + } + else + { + // ... then try after. + const_iterator __after = __position; + if (__position._M_node == _M_rightmost()) + return _M_insert(0, _M_rightmost(), __v); + else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node), + _KeyOfValue()(__v))) + { + if (_S_right(__position._M_node) == 0) + return _M_insert(0, __position._M_node, __v); + else + return _M_insert(__after._M_node, __after._M_node, __v); + } + else + return const_iterator(insert_equal(__v)); + } + } + template template @@ -1022,13 +1168,13 @@ namespace std template template - void - _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>:: - insert_unique(_II __first, _II __last) - { - for (; __first != __last; ++__first) - insert_unique(end(), *__first); - } + void + _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>:: + insert_unique(_II __first, _II __last) + { + for (; __first != __last; ++__first) + insert_unique(end(), *__first); + } template @@ -1044,6 +1190,20 @@ namespace std --_M_impl._M_node_count; } + template + inline void + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + erase(const_iterator __position) + { + _Link_type __y = + static_cast<_Link_type>(_Rb_tree_rebalance_for_erase + (const_cast<_Base_ptr>(__position._M_node), + this->_M_impl._M_header)); + destroy_node(__y); + --_M_impl._M_node_count; + } + template typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type @@ -1121,6 +1281,19 @@ namespace std erase(__first++); } + template + void + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + erase(const_iterator __first, const_iterator __last) + { + if (__first == begin() && __last == end()) + clear(); + else + while (__first != __last) + erase(__first++); + } + template void