From 36edf9cab1d4a444497c2aaf57c4ce61f7a67901 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fran=C3=A7ois=20Dumont?= Date: Fri, 4 Oct 2019 20:22:11 +0000 Subject: [PATCH] Improve _GLIBCXX_DEBUG safe iterator range size computation. * include/debug/forward_list (_Sequence_traits<__debug::forward_list<>>::_S_size): Returns __dp_sign distance when not empty. * include/debug/list (_Sequence_traits<__debug::list<>>::_S_size): Likewise. * include/debug/helper_functions.h (__dp_sign_max_size): New _Distance_precision enum entry. (__valid_range_aux(_IIte, _IIte, _Distance_traits<>::__type, __false_type)): Adapt. * include/debug/safe_iterator.tcc (_Safe_iterator<>::_M_get_distance_to(const _Safe_iterator&)): Review distance computation. From-SVN: r276600 --- libstdc++-v3/ChangeLog | 15 ++++++ libstdc++-v3/include/debug/forward_list | 2 +- libstdc++-v3/include/debug/helper_functions.h | 10 ++-- libstdc++-v3/include/debug/list | 2 +- libstdc++-v3/include/debug/safe_iterator.tcc | 46 +++++++++++++------ 5 files changed, 54 insertions(+), 21 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 4e822def3fe..26d37d7effb 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,18 @@ +2019-10-04 François Dumont + + * include/debug/forward_list + (_Sequence_traits<__debug::forward_list<>>::_S_size): Returns __dp_sign + distance when not empty. + * include/debug/list (_Sequence_traits<__debug::list<>>::_S_size): + Likewise. + * include/debug/helper_functions.h (__dp_sign_max_size): New + _Distance_precision enum entry. + (__valid_range_aux(_IIte, _IIte, _Distance_traits<>::__type, + __false_type)): Adapt. + * include/debug/safe_iterator.tcc + (_Safe_iterator<>::_M_get_distance_to(const _Safe_iterator&)): Review + distance computation. + 2019-10-04 Jonathan Wakely PR libstdc++/81091 diff --git a/libstdc++-v3/include/debug/forward_list b/libstdc++-v3/include/debug/forward_list index e30b000009e..f1756ddec9d 100644 --- a/libstdc++-v3/include/debug/forward_list +++ b/libstdc++-v3/include/debug/forward_list @@ -911,7 +911,7 @@ namespace __gnu_debug _S_size(const std::__debug::forward_list<_Tp, _Alloc>& __seq) { return __seq.empty() - ? std::make_pair(0, __dp_exact) : std::make_pair(1, __dp_equality); + ? std::make_pair(0, __dp_exact) : std::make_pair(1, __dp_sign); } }; diff --git a/libstdc++-v3/include/debug/helper_functions.h b/libstdc++-v3/include/debug/helper_functions.h index 475fdda1d7b..5a920bb9a6f 100644 --- a/libstdc++-v3/include/debug/helper_functions.h +++ b/libstdc++-v3/include/debug/helper_functions.h @@ -50,10 +50,11 @@ namespace __gnu_debug */ enum _Distance_precision { - __dp_none, // Not even an iterator type - __dp_equality, //< Can compare iterator equality, only - __dp_sign, //< Can determine equality and ordering - __dp_exact //< Can determine distance precisely + __dp_none, // Not even an iterator type + __dp_equality, //< Can compare iterator equality, only + __dp_sign, //< Can determine equality and ordering + __dp_sign_max_size, //< __dp_sign and gives max range size + __dp_exact //< Can determine distance precisely }; template= 0; } diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list index 5eb9a6094e3..140546a633e 100644 --- a/libstdc++-v3/include/debug/list +++ b/libstdc++-v3/include/debug/list @@ -916,7 +916,7 @@ namespace __gnu_debug _S_size(const std::__debug::list<_Tp, _Alloc>& __seq) { return __seq.empty() - ? std::make_pair(0, __dp_exact) : std::make_pair(1, __dp_equality); + ? std::make_pair(0, __dp_exact) : std::make_pair(1, __dp_sign); } }; #endif diff --git a/libstdc++-v3/include/debug/safe_iterator.tcc b/libstdc++-v3/include/debug/safe_iterator.tcc index 581c51c9607..1750bc473d2 100644 --- a/libstdc++-v3/include/debug/safe_iterator.tcc +++ b/libstdc++-v3/include/debug/safe_iterator.tcc @@ -113,18 +113,22 @@ namespace __gnu_debug _Safe_iterator<_Iterator, _Sequence, _Category>:: _M_get_distance_to(const _Safe_iterator& __rhs) const { - typedef typename _Distance_traits<_Iterator>::__type _Diff; + typedef typename _Distance_traits<_Iterator>::__type _Dist; typedef _Sequence_traits<_Sequence> _SeqTraits; - if (this->base() == __rhs.base()) - return std::make_pair(0, __dp_exact); + _Dist __base_dist = __get_distance(this->base(), __rhs.base()); + if (__base_dist.second == __dp_exact) + return __base_dist; + _Dist __seq_dist = _SeqTraits::_S_size(*this->_M_get_sequence()); if (this->_M_is_before_begin()) { if (__rhs._M_is_begin()) return std::make_pair(1, __dp_exact); - return std::make_pair(1, __dp_sign); + return __seq_dist.second == __dp_exact + ? std::make_pair(__seq_dist.first + 1, __dp_exact) + : __seq_dist; } if (this->_M_is_begin()) @@ -133,30 +137,42 @@ namespace __gnu_debug return std::make_pair(-1, __dp_exact); if (__rhs._M_is_end()) - return _SeqTraits::_S_size(*this->_M_get_sequence()); + return __seq_dist; - return std::make_pair(1, __dp_sign); + return std::make_pair(__seq_dist.first, + __seq_dist.second == __dp_exact + ? __dp_sign_max_size : __seq_dist.second); } if (this->_M_is_end()) { if (__rhs._M_is_before_begin()) - return std::make_pair(-1, __dp_exact); + return __seq_dist.second == __dp_exact + ? std::make_pair(-__seq_dist.first - 1, __dp_exact) + : std::make_pair(-__seq_dist.first, __dp_sign); if (__rhs._M_is_begin()) - { - _Diff __diff = _SeqTraits::_S_size(*this->_M_get_sequence()); - return std::make_pair(-__diff.first, __diff.second); - } + return std::make_pair(-__seq_dist.first, __seq_dist.second); - return std::make_pair(-1, __dp_sign); + return std::make_pair(-__seq_dist.first, + __seq_dist.second == __dp_exact + ? __dp_sign_max_size : __seq_dist.second); } - if (__rhs._M_is_before_begin() || __rhs._M_is_begin()) - return std::make_pair(-1, __dp_sign); + if (__rhs._M_is_before_begin()) + return __seq_dist.second == __dp_exact + ? std::make_pair(__seq_dist.first - 1, __dp_exact) + : std::make_pair(-__seq_dist.first, __dp_sign); + + if (__rhs._M_is_begin()) + return std::make_pair(-__seq_dist.first, + __seq_dist.second == __dp_exact + ? __dp_sign_max_size : __seq_dist.second); if (__rhs._M_is_end()) - return std::make_pair(1, __dp_sign); + return std::make_pair(__seq_dist.first, + __seq_dist.second == __dp_exact + ? __dp_sign_max_size : __seq_dist.second); return std::make_pair(1, __dp_equality); } -- 2.30.2