From: François Dumont Date: Fri, 1 Jan 2021 16:35:56 +0000 (+0100) Subject: libstdc++: Implement N3644 for _GLIBCXX_DEBUG iterators X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=05a30af3f237984b4dcf1dbbc17fdac583c46506;p=gcc.git libstdc++: Implement N3644 for _GLIBCXX_DEBUG iterators libstdc++-v3/ChangeLog: PR libstdc++/98466 * include/bits/hashtable_policy.h (_Node_iterator_base()): Set _M_cur to nullptr. (_Node_iterator()): Make default. (_Node_const_iterator()): Make default. * include/debug/macros.h (__glibcxx_check_erae_range_after): Add _M_singular iterator checks. * include/debug/safe_iterator.h (_GLIBCXX_DEBUG_VERIFY_OPERANDS): Accept if both iterator are value initialized. * include/debug/safe_local_iterator.h (_GLIBCXX_DEBUG_VERIFY_OPERANDS): Likewise. * include/debug/safe_iterator.tcc (_Safe_iterator<>::_M_valid_range): Add _M_singular checks on input iterators. * src/c++11/debug.cc (_Safe_iterator_base::_M_can_compare): Remove _M_singular checks. * testsuite/23_containers/deque/debug/98466.cc: New test. * testsuite/23_containers/unordered_map/debug/98466.cc: New test. --- diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h index 84961849fb4..999147a68d4 100644 --- a/libstdc++-v3/include/bits/hashtable_policy.h +++ b/libstdc++-v3/include/bits/hashtable_policy.h @@ -290,7 +290,7 @@ namespace __detail __node_type* _M_cur; - _Node_iterator_base() = default; + _Node_iterator_base() : _M_cur(nullptr) { } _Node_iterator_base(__node_type* __p) noexcept : _M_cur(__p) { } @@ -331,8 +331,7 @@ namespace __detail using reference = typename std::conditional<__constant_iterators, const value_type&, value_type&>::type; - _Node_iterator() noexcept - : __base_type(nullptr) { } + _Node_iterator() = default; explicit _Node_iterator(__node_type* __p) noexcept @@ -379,8 +378,7 @@ namespace __detail typedef const value_type* pointer; typedef const value_type& reference; - _Node_const_iterator() noexcept - : __base_type(nullptr) { } + _Node_const_iterator() = default; explicit _Node_const_iterator(__node_type* __p) noexcept diff --git a/libstdc++-v3/include/debug/macros.h b/libstdc++-v3/include/debug/macros.h index 08c49eca554..0988437046f 100644 --- a/libstdc++-v3/include/debug/macros.h +++ b/libstdc++-v3/include/debug/macros.h @@ -244,6 +244,11 @@ _GLIBCXX_DEBUG_VERIFY(_First._M_attached_to(this), \ * valid iterator range within this sequence. */ #define __glibcxx_check_erase_range_after(_First,_Last) \ +_GLIBCXX_DEBUG_VERIFY(!_First._M_singular() && !_Last._M_singular(), \ + _M_message(__gnu_debug::__msg_erase_different) \ + ._M_sequence(*this, "this") \ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last)); \ _GLIBCXX_DEBUG_VERIFY(_First._M_can_compare(_Last), \ _M_message(__gnu_debug::__msg_erase_different) \ ._M_sequence(*this, "this") \ diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h index 11e0f0b14a3..a10df190969 100644 --- a/libstdc++-v3/include/debug/safe_iterator.h +++ b/libstdc++-v3/include/debug/safe_iterator.h @@ -40,7 +40,9 @@ #endif #define _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, _BadMsgId, _DiffMsgId) \ - _GLIBCXX_DEBUG_VERIFY(!_Lhs._M_singular() && !_Rhs._M_singular(), \ + _GLIBCXX_DEBUG_VERIFY(!_Lhs._M_singular() && !_Rhs._M_singular() \ + || (_Lhs.base() == _Iterator() \ + && _Rhs.base() == _Iterator()), \ _M_message(_BadMsgId) \ ._M_iterator(_Lhs, #_Lhs) \ ._M_iterator(_Rhs, #_Rhs)); \ diff --git a/libstdc++-v3/include/debug/safe_iterator.tcc b/libstdc++-v3/include/debug/safe_iterator.tcc index 7d6f91782d5..81deb10125b 100644 --- a/libstdc++-v3/include/debug/safe_iterator.tcc +++ b/libstdc++-v3/include/debug/safe_iterator.tcc @@ -186,7 +186,7 @@ namespace __gnu_debug std::pair& __dist, bool __check_dereferenceable) const { - if (!_M_can_compare(__rhs)) + if (_M_singular() || __rhs._M_singular() || !_M_can_compare(__rhs)) return false; /* Determine iterators order */ @@ -217,7 +217,8 @@ namespace __gnu_debug std::pair& __dist) const { - if (!this->_M_can_compare(__rhs)) + if (this->_M_singular() || __rhs._M_singular() + || !this->_M_can_compare(__rhs)) return false; /* Determine iterators order */ diff --git a/libstdc++-v3/include/debug/safe_local_iterator.h b/libstdc++-v3/include/debug/safe_local_iterator.h index 39bb9790e05..31c48e65a24 100644 --- a/libstdc++-v3/include/debug/safe_local_iterator.h +++ b/libstdc++-v3/include/debug/safe_local_iterator.h @@ -32,7 +32,9 @@ #include #define _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs) \ - _GLIBCXX_DEBUG_VERIFY(!_Lhs._M_singular() && !_Rhs._M_singular(), \ + _GLIBCXX_DEBUG_VERIFY(!_Lhs._M_singular() && !_Rhs._M_singular() \ + || (_Lhs.base() == _Iterator{} \ + && _Rhs.base() == _Iterator{}), \ _M_message(__msg_iter_compare_bad) \ ._M_iterator(_Lhs, "lhs") \ ._M_iterator(_Rhs, "rhs")); \ diff --git a/libstdc++-v3/src/c++11/debug.cc b/libstdc++-v3/src/c++11/debug.cc index 6cf99186a82..5a642097d17 100644 --- a/libstdc++-v3/src/c++11/debug.cc +++ b/libstdc++-v3/src/c++11/debug.cc @@ -424,10 +424,7 @@ namespace __gnu_debug bool _Safe_iterator_base:: _M_can_compare(const _Safe_iterator_base& __x) const throw () - { - return (!_M_singular() - && !__x._M_singular() && _M_sequence == __x._M_sequence); - } + { return _M_sequence == __x._M_sequence; } __gnu_cxx::__mutex& _Safe_iterator_base:: diff --git a/libstdc++-v3/testsuite/23_containers/deque/debug/98466.cc b/libstdc++-v3/testsuite/23_containers/deque/debug/98466.cc new file mode 100644 index 00000000000..720977e5622 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/deque/debug/98466.cc @@ -0,0 +1,38 @@ +// Copyright (C) 2021 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do run { target c++11 } } + +#include +#include + +// PR libstdc++/98466 + +void test01() +{ + __gnu_debug::deque::iterator it{}; + VERIFY( it == it ); + + __gnu_debug::deque::const_iterator cit{}; + VERIFY( cit == cit ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/debug/98466.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/98466.cc new file mode 100644 index 00000000000..cc22b9ff80a --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_map/debug/98466.cc @@ -0,0 +1,44 @@ +// Copyright (C) 2021 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do run { target c++11 } } + +#include +#include + +// PR libstdc++/98466 + +void test01() +{ + __gnu_debug::unordered_map::iterator it{}; + VERIFY( it == it ); + + __gnu_debug::unordered_map::const_iterator cit{}; + VERIFY( cit == cit ); + + __gnu_debug::unordered_map::local_iterator lit{}; + VERIFY( lit == lit ); + + __gnu_debug::unordered_map::const_local_iterator clit{}; + VERIFY( clit == clit ); +} + +int main() +{ + test01(); + return 0; +}