diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 31ada067658..3149f380038 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,18 @@ +2013-10-25 François Dumont + + * include/debug/formatter.h (__check_singular): Add const on + iterator reference. + * include/debug/functions.h (__check_singular): Likewise. + (__check_singular(const _Safe_iterator<_Ite, _Seq>&)): Delete. + (__check_dereferenceable(const _Ite&)): Add const on iterator + reference. + (__check_dereferenceable(const _Safe_local_iterator<>&)): New. + * include/debug/safe_iterator.h (__check_singular_aux): Review + comment. + * testsuite/23_containers/vector/debug/debug_functions.cc: New. + * testsuite/23_containers/unordered_set/debug/debug_functions.cc: + New. + 2013-10-23 Chris Jefferson Paolo Carlini diff --git a/libstdc++-v3/include/debug/formatter.h b/libstdc++-v3/include/debug/formatter.h index 15dd8d73797..2af169b13fc 100644 --- a/libstdc++-v3/include/debug/formatter.h +++ b/libstdc++-v3/include/debug/formatter.h @@ -38,7 +38,7 @@ namespace __gnu_debug using std::type_info; template - bool __check_singular(_Iterator&); + bool __check_singular(const _Iterator&); class _Safe_sequence_base; diff --git a/libstdc++-v3/include/debug/functions.h b/libstdc++-v3/include/debug/functions.h index 8e76b7f2ee5..4d8fe21719c 100644 --- a/libstdc++-v3/include/debug/functions.h +++ b/libstdc++-v3/include/debug/functions.h @@ -45,6 +45,9 @@ namespace __gnu_debug template class _Safe_iterator; + template + class _Safe_local_iterator; + template struct _Insert_range_from_self_is_safe { enum { __value = 0 }; }; @@ -57,7 +60,7 @@ namespace __gnu_debug // a _Safe_iterator. template inline bool - __check_singular(_Iterator& __x) + __check_singular(const _Iterator& __x) { return __check_singular_aux(&__x); } /** Non-NULL pointers are nonsingular. */ @@ -66,17 +69,11 @@ namespace __gnu_debug __check_singular(const _Tp* __ptr) { return __ptr == 0; } - /** Safe iterators know if they are singular. */ - template - inline bool - __check_singular(const _Safe_iterator<_Iterator, _Sequence>& __x) - { return __x._M_singular(); } - /** Assume that some arbitrary iterator is dereferenceable, because we can't prove that it isn't. */ template inline bool - __check_dereferenceable(_Iterator&) + __check_dereferenceable(const _Iterator&) { return true; } /** Non-NULL pointers are dereferenceable. */ @@ -85,12 +82,19 @@ namespace __gnu_debug __check_dereferenceable(const _Tp* __ptr) { return __ptr; } - /** Safe iterators know if they are singular. */ + /** Safe iterators know if they are dereferenceable. */ template inline bool __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x) { return __x._M_dereferenceable(); } + /** Safe local iterators know if they are dereferenceable. */ + template + inline bool + __check_dereferenceable(const _Safe_local_iterator<_Iterator, + _Sequence>& __x) + { return __x._M_dereferenceable(); } + /** If the distance between two random access iterators is * nonnegative, assume the range is valid. */ diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h index d5adefd0ace..9e73bcfd985 100644 --- a/libstdc++-v3/include/debug/safe_iterator.h +++ b/libstdc++-v3/include/debug/safe_iterator.h @@ -56,10 +56,9 @@ namespace __gnu_debug { return __it == __seq->_M_base().begin(); } }; - /** Iterators that derive from _Safe_iterator_base but that aren't - * _Safe_iterators can be determined singular or non-singular via - * _Safe_iterator_base. - */ + /** Iterators that derive from _Safe_iterator_base can be determined singular + * or non-singular. + **/ inline bool __check_singular_aux(const _Safe_iterator_base* __x) { return __x->_M_singular(); } diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/debug/debug_functions.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/debug_functions.cc new file mode 100644 index 00000000000..b90249f2d70 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/unordered_set/debug/debug_functions.cc @@ -0,0 +1,92 @@ +// Copyright (C) 2013 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-options "-std=gnu++11" } +// { dg-require-debug-mode "" } + +#include +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + using namespace __gnu_debug; + + std::unordered_set u = { 0, 1, 2 }; + VERIFY( __check_dereferenceable(u.begin()) ); + auto it = u.begin(); + VERIFY( __check_dereferenceable(it) ); + + VERIFY( __check_dereferenceable(u.cbegin()) ); + auto cit = u.begin(); + VERIFY( __check_dereferenceable(cit) ); + + VERIFY( !__check_dereferenceable(u.end()) ); + it = u.end(); + VERIFY( !__check_dereferenceable(it) ); + + auto bucket = u.bucket(0); + VERIFY( __check_dereferenceable(u.begin(bucket)) ); + auto lit = u.begin(bucket); + VERIFY( __check_dereferenceable(lit) ); + + VERIFY( !__check_dereferenceable(u.end(bucket)) ); +} + +void test02() +{ + bool test __attribute__((unused)) = true; + using namespace __gnu_debug; + + std::unordered_set u = { 0, 1, 2 }; + + VERIFY( !__check_singular(u.end()) ); + auto it = u.end(); + VERIFY( !__check_singular(it) ); + + VERIFY( !__check_singular(u.begin()) ); + it = u.begin(); + VERIFY( !__check_singular(it) ); + + u.clear(); + + VERIFY( it._M_singular() ); + VERIFY( __check_singular(it) ); + + it = u.end(); + VERIFY( !it._M_singular() ); + VERIFY( !__check_singular(it) ); + + u = { 0, 1, 2 }; + + auto bucket = u.bucket(0); + VERIFY( !__check_singular(u.begin(bucket)) ); + auto lit = u.begin(bucket); + VERIFY( !__check_singular(lit) ); + + VERIFY( !__check_singular(u.end(bucket)) ); + + u.clear(); + VERIFY( __check_singular(lit) ); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/debug/debug_functions.cc b/libstdc++-v3/testsuite/23_containers/vector/debug/debug_functions.cc new file mode 100644 index 00000000000..5568ed65cf2 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/debug/debug_functions.cc @@ -0,0 +1,75 @@ +// Copyright (C) 2013 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-require-debug-mode "" } + +#include +#include + +void test01() +{ + bool test __attribute__((unused)) = true; + using namespace __gnu_debug; + + std::vector v1(3, 1); + VERIFY( __check_dereferenceable(v1.begin()) ); + std::vector::iterator it = v1.begin(); + VERIFY( __check_dereferenceable(it) ); + + VERIFY( !__check_dereferenceable(v1.end()) ); + it = v1.end(); + VERIFY( !__check_dereferenceable(it) ); + + const volatile int* pi = 0; + VERIFY( !__check_dereferenceable(pi) ); + + int i; + pi = &i; + + VERIFY( __check_dereferenceable(pi) ); +} + +void test02() +{ + bool test __attribute__((unused)) = true; + using namespace __gnu_debug; + + std::vector v1(3, 1); + VERIFY( !__check_singular(v1.begin()) ); + std::vector::iterator it = v1.begin(); + VERIFY( !__check_singular(it) ); + + VERIFY( !__check_singular(v1.end()) ); + it = v1.end(); + VERIFY( !__check_singular(it) ); + + v1.clear(); + + VERIFY( it._M_singular() ); + VERIFY( __check_singular(it) ); + + it = v1.end(); + VERIFY( !it._M_singular() ); + VERIFY( !__check_singular(it) ); +} + +int main() +{ + test01(); + test02(); + return 0; +}