On 10/24/2013 12:12 AM, Paolo Carlini wrote:
On 10/23/2013 11:22 PM, François Dumont wrote:
You are right, I am preparing a test case. However you have to know
that __check_dereferenceable is simply not used for the moment. It is
only because I have started using it for a debug mode evolution that
I discovered the issue.
Ok, thanks. Now however I'm curious to know the story of
__check_dereferenceable: dates back to when Doug added debug-mode and
never used since? Any idea?
Paolo.
Don't know __check_dereferenceable story, nothing in ChangeLogs.
Here is my new proposal with tests. I finally restore
__check_singular_aux, don't know why __check_singular(const
_Safe_Iterator<>&) didn't work. I even completely removed it as
__check_singular_aux works well for all kind of safe iterators
inheriting from _Safe_iterator_base.
2013-10-24 François Dumont <fdum...@gcc.gnu.org>
* 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.
Tested under Linux x86_64, normal and debug mode.
Ok to commit ?
François
Index: include/debug/formatter.h
===================================================================
--- include/debug/formatter.h (revision 204032)
+++ include/debug/formatter.h (working copy)
@@ -38,7 +38,7 @@
using std::type_info;
template<typename _Iterator>
- bool __check_singular(_Iterator&);
+ bool __check_singular(const _Iterator&);
class _Safe_sequence_base;
Index: include/debug/functions.h
===================================================================
--- include/debug/functions.h (revision 204032)
+++ include/debug/functions.h (working copy)
@@ -45,6 +45,9 @@
template<typename _Iterator, typename _Sequence>
class _Safe_iterator;
+ template<typename _Iterator, typename _Sequence>
+ class _Safe_local_iterator;
+
template<typename _Sequence>
struct _Insert_range_from_self_is_safe
{ enum { __value = 0 }; };
@@ -57,7 +60,7 @@
// a _Safe_iterator.
template<typename _Iterator>
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 @@
__check_singular(const _Tp* __ptr)
{ return __ptr == 0; }
- /** Safe iterators know if they are singular. */
- template<typename _Iterator, typename _Sequence>
- 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<typename _Iterator>
inline bool
- __check_dereferenceable(_Iterator&)
+ __check_dereferenceable(const _Iterator&)
{ return true; }
/** Non-NULL pointers are dereferenceable. */
@@ -85,12 +82,19 @@
__check_dereferenceable(const _Tp* __ptr)
{ return __ptr; }
- /** Safe iterators know if they are singular. */
+ /** Safe iterators know if they are dereferenceable. */
template<typename _Iterator, typename _Sequence>
inline bool
__check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x)
{ return __x._M_dereferenceable(); }
+ /** Safe local iterators know if they are dereferenceable. */
+ template<typename _Iterator, typename _Sequence>
+ 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.
*/
Index: include/debug/safe_iterator.h
===================================================================
--- include/debug/safe_iterator.h (revision 204032)
+++ include/debug/safe_iterator.h (working copy)
@@ -56,10 +56,9 @@
{ 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(); }
Index: testsuite/23_containers/unordered_set/debug/debug_functions.cc
===================================================================
--- testsuite/23_containers/unordered_set/debug/debug_functions.cc (revision 0)
+++ testsuite/23_containers/unordered_set/debug/debug_functions.cc (revision 0)
@@ -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
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-options "-std=gnu++11" }
+// { dg-require-debug-mode "" }
+
+#include <unordered_set>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ using namespace __gnu_debug;
+
+ std::unordered_set<int> 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<int> 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;
+}
Index: testsuite/23_containers/vector/debug/debug_functions.cc
===================================================================
--- testsuite/23_containers/vector/debug/debug_functions.cc (revision 0)
+++ testsuite/23_containers/vector/debug/debug_functions.cc (revision 0)
@@ -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
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+
+#include <vector>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+ using namespace __gnu_debug;
+
+ std::vector<int> v1(3, 1);
+ VERIFY( __check_dereferenceable(v1.begin()) );
+ std::vector<int>::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<int> v1(3, 1);
+ VERIFY( !__check_singular(v1.begin()) );
+ std::vector<int>::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;
+}