[committed] libstdc++: Fix _ForwardIteratorConcept for __gnu_debug::vector<bool>

Jonathan Wakely jwakely@redhat.com
Fri Oct 1 14:04:57 GMT 2021


The recent changes to the _GLIBCXX_CONCEPT_CHECKS checks for forward
iterators don't work for vector<bool> iterators in debug mode, because
the _Safe_iterator specializations don't match the special cases I added
for _Bit_iterator and _Bit_const_iterator.

This refactors the _ForwardIteratorReferenceConcept class template to
identify vector<bool> iterators using a new trait, which also works for
debug iterators.

libstdc++-v3/ChangeLog:

	* include/bits/boost_concept_check.h (_Is_vector_bool_iterator):
	New trait to identify vector<bool> iterators, including debug
	ones.
	(_ForwardIteratorReferenceConcept): Add default template
	argument using _Is_vector_bool_iterator and use it in partial
	specialization for the vector<bool> cases.
	(_Mutable_ForwardIteratorReferenceConcept): Likewise.
	* testsuite/24_iterators/operations/prev_neg.cc: Adjust dg-error
	line number.

Tested x86_64-linux. Committed to trunk.

-------------- next part --------------
commit c67339d12653c33f85f8141789d7a7cf38831cbd
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Sep 30 11:25:15 2021

    libstdc++: Fix _ForwardIteratorConcept for __gnu_debug::vector<bool>
    
    The recent changes to the _GLIBCXX_CONCEPT_CHECKS checks for forward
    iterators don't work for vector<bool> iterators in debug mode, because
    the _Safe_iterator specializations don't match the special cases I added
    for _Bit_iterator and _Bit_const_iterator.
    
    This refactors the _ForwardIteratorReferenceConcept class template to
    identify vector<bool> iterators using a new trait, which also works for
    debug iterators.
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/boost_concept_check.h (_Is_vector_bool_iterator):
            New trait to identify vector<bool> iterators, including debug
            ones.
            (_ForwardIteratorReferenceConcept): Add default template
            argument using _Is_vector_bool_iterator and use it in partial
            specialization for the vector<bool> cases.
            (_Mutable_ForwardIteratorReferenceConcept): Likewise.
            * testsuite/24_iterators/operations/prev_neg.cc: Adjust dg-error
            line number.

diff --git a/libstdc++-v3/include/bits/boost_concept_check.h b/libstdc++-v3/include/bits/boost_concept_check.h
index 71c99c13e93..81352518c50 100644
--- a/libstdc++-v3/include/bits/boost_concept_check.h
+++ b/libstdc++-v3/include/bits/boost_concept_check.h
@@ -47,11 +47,19 @@
 namespace std  _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
+_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   struct _Bit_iterator;
   struct _Bit_const_iterator;
+_GLIBCXX_END_NAMESPACE_CONTAINER
 _GLIBCXX_END_NAMESPACE_VERSION
 }
 
+namespace __gnu_debug
+{
+  template<typename _Iterator, typename _Sequence, typename _Category>
+    class _Safe_iterator;
+}
+
 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -478,10 +486,32 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
     _ValueT __val() const;
   };
 
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-variable"
+  template<typename _Tp>
+  struct _Is_vector_bool_iterator
+  { static const bool __value = false; };
 
-  template <class _Tp>
+#ifdef _GLIBCXX_DEBUG
+  namespace __cont = ::std::_GLIBCXX_STD_C;
+#else
+  namespace __cont = ::std;
+#endif
+
+  // Trait to identify vector<bool>::iterator
+  template <>
+  struct _Is_vector_bool_iterator<__cont::_Bit_iterator>
+  { static const bool __value = true; };
+
+  // And for vector<bool>::const_iterator.
+  template <>
+  struct _Is_vector_bool_iterator<__cont::_Bit_const_iterator>
+  { static const bool __value = true; };
+
+  // And for __gnu_debug::vector<bool> iterators too.
+  template <typename _It, typename _Seq, typename _Tag>
+  struct _Is_vector_bool_iterator<__gnu_debug::_Safe_iterator<_It, _Seq, _Tag> >
+  : _Is_vector_bool_iterator<_It> { };
+
+  template <class _Tp, bool = _Is_vector_bool_iterator<_Tp>::__value>
   struct _ForwardIteratorReferenceConcept
   {
     void __constraints() {
@@ -493,7 +523,7 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
     }
   };
 
-  template <class _Tp>
+  template <class _Tp, bool = _Is_vector_bool_iterator<_Tp>::__value>
   struct _Mutable_ForwardIteratorReferenceConcept
   {
     void __constraints() {
@@ -503,26 +533,22 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
     }
   };
 
-  // vector<bool>::iterator is not a real forward reference, but pretend it is.
-  template <>
-  struct _ForwardIteratorReferenceConcept<std::_Bit_iterator>
+  // vector<bool> iterators are not real forward iterators, but we ignore that.
+  template <class _Tp>
+  struct _ForwardIteratorReferenceConcept<_Tp, true>
   {
     void __constraints() { }
   };
 
-  // vector<bool>::iterator is not a real forward reference, but pretend it is.
-  template <>
-  struct _Mutable_ForwardIteratorReferenceConcept<std::_Bit_iterator>
+  // vector<bool> iterators are not real forward iterators, but we ignore that.
+  template <class _Tp>
+  struct _Mutable_ForwardIteratorReferenceConcept<_Tp, true>
   {
     void __constraints() { }
   };
 
-  // And vector<bool>::const iterator too.
-  template <>
-  struct _ForwardIteratorReferenceConcept<std::_Bit_const_iterator>
-  {
-    void __constraints() { }
-  };
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-variable"
 
   template <class _Tp>
   struct _ForwardIteratorConcept
diff --git a/libstdc++-v3/testsuite/24_iterators/operations/prev_neg.cc b/libstdc++-v3/testsuite/24_iterators/operations/prev_neg.cc
index d22491999a8..cc648549a06 100644
--- a/libstdc++-v3/testsuite/24_iterators/operations/prev_neg.cc
+++ b/libstdc++-v3/testsuite/24_iterators/operations/prev_neg.cc
@@ -38,5 +38,5 @@ test02()
 {
   const Y array[1] = { };
   (void) std::prev(array + 1);
-  // { dg-error "forward_iterator" "" { target *-*-* } 231 }
+  // { dg-error "forward_iterator" "" { target *-*-* } 239 }
 }


More information about the Gcc-patches mailing list