aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrançois Dumont <fdumont@gcc.gnu.org>2019-10-04 20:22:11 +0000
committerFrançois Dumont <fdumont@gcc.gnu.org>2019-10-04 20:22:11 +0000
commit36edf9cab1d4a444497c2aaf57c4ce61f7a67901 (patch)
treea88be7904712db89fc6c702cc4caf00bb41b371d
parent9af0d5ef3b14a9b3e4b0cb6aaaaba44ea722fb06 (diff)
downloadgcc-36edf9cab1d4a444497c2aaf57c4ce61f7a67901.zip
gcc-36edf9cab1d4a444497c2aaf57c4ce61f7a67901.tar.gz
gcc-36edf9cab1d4a444497c2aaf57c4ce61f7a67901.tar.bz2
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
-rw-r--r--libstdc++-v3/ChangeLog15
-rw-r--r--libstdc++-v3/include/debug/forward_list2
-rw-r--r--libstdc++-v3/include/debug/helper_functions.h10
-rw-r--r--libstdc++-v3/include/debug/list2
-rw-r--r--libstdc++-v3/include/debug/safe_iterator.tcc46
5 files changed, 54 insertions, 21 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 4e822de..26d37d7 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,18 @@
+2019-10-04 François Dumont <fdumont@gcc.gnu.org>
+
+ * 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 <jwakely@redhat.com>
PR libstdc++/81091
diff --git a/libstdc++-v3/include/debug/forward_list b/libstdc++-v3/include/debug/forward_list
index e30b000..f1756dd 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 475fdda..5a920bb 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<typename _Iterator,
@@ -176,6 +177,7 @@ namespace __gnu_debug
return true;
break;
case __dp_sign:
+ case __dp_sign_max_size:
case __dp_exact:
return __dist.first >= 0;
}
diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list
index 5eb9a60..140546a 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 581c51c..1750bc4 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);
}