* [committed] libstdc++: Fix concept checks for iterators
@ 2021-09-28 19:26 Jonathan Wakely
0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2021-09-28 19:26 UTC (permalink / raw)
To: libstdc++, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 992 bytes --]
This adds some additional checks the the C++98-style concept checks for
iterators, and removes some bogus checks for mutable iterators. Instead
of requiring that the result of dereferencing a mutable iterator is
assignable (which is a property of the value type, not required for the
iterator) check that the reference type is a non-const reference to the
value type.
Signed-off-by: Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/ChangeLog:
* include/bits/boost_concept_check.h (_ForwardIteratorConcept)
(_BidirectionalIteratorConcept, _RandomAccessIteratorConcept):
Check result types of iterator operations.
(_Mutable_ForwardIteratorConcept): Check that iterator's
reference type is a reference to its value type.
(_Mutable_BidirectionalIteratorConcept): Do not require the
value type to be assignable.
(_Mutable_RandomAccessIteratorConcept): Likewise.
* testsuite/24_iterators/operations/prev_neg.cc: Adjust dg-error
line number.
Tested x86_64-linux. Committed to trunk.
[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 7746 bytes --]
commit afffc96a5259ba4e3f3cca154dc5ea32a496875e
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Fri Sep 24 13:56:33 2021
libstdc++: Fix concept checks for iterators
This adds some additional checks the the C++98-style concept checks for
iterators, and removes some bogus checks for mutable iterators. Instead
of requiring that the result of dereferencing a mutable iterator is
assignable (which is a property of the value type, not required for the
iterator) check that the reference type is a non-const reference to the
value type.
Signed-off-by: Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/ChangeLog:
* include/bits/boost_concept_check.h (_ForwardIteratorConcept)
(_BidirectionalIteratorConcept, _RandomAccessIteratorConcept):
Check result types of iterator operations.
(_Mutable_ForwardIteratorConcept): Check that iterator's
reference type is a reference to its value type.
(_Mutable_BidirectionalIteratorConcept): Do not require the
value type to be assignable.
(_Mutable_RandomAccessIteratorConcept): 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 ba36c24abec..71c99c13e93 100644
--- a/libstdc++-v3/include/bits/boost_concept_check.h
+++ b/libstdc++-v3/include/bits/boost_concept_check.h
@@ -44,6 +44,14 @@
#include <bits/c++config.h>
#include <bits/stl_iterator_base_types.h> // for traits and tags
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+ struct _Bit_iterator;
+ struct _Bit_const_iterator;
+_GLIBCXX_END_NAMESPACE_VERSION
+}
+
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -470,6 +478,52 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
_ValueT __val() const;
};
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-variable"
+
+ template <class _Tp>
+ struct _ForwardIteratorReferenceConcept
+ {
+ void __constraints() {
+#if __cplusplus >= 201103L
+ typedef typename std::iterator_traits<_Tp>::reference _Ref;
+ static_assert(std::is_reference<_Ref>::value,
+ "reference type of a forward iterator must be a real reference");
+#endif
+ }
+ };
+
+ template <class _Tp>
+ struct _Mutable_ForwardIteratorReferenceConcept
+ {
+ void __constraints() {
+ typedef typename std::iterator_traits<_Tp>::reference _Ref;
+ typedef typename std::iterator_traits<_Tp>::value_type _Val;
+ __function_requires< _SameTypeConcept<_Ref, _Val&> >();
+ }
+ };
+
+ // vector<bool>::iterator is not a real forward reference, but pretend it is.
+ template <>
+ struct _ForwardIteratorReferenceConcept<std::_Bit_iterator>
+ {
+ void __constraints() { }
+ };
+
+ // vector<bool>::iterator is not a real forward reference, but pretend it is.
+ template <>
+ struct _Mutable_ForwardIteratorReferenceConcept<std::_Bit_iterator>
+ {
+ void __constraints() { }
+ };
+
+ // And vector<bool>::const iterator too.
+ template <>
+ struct _ForwardIteratorReferenceConcept<std::_Bit_const_iterator>
+ {
+ void __constraints() { }
+ };
+
template <class _Tp>
struct _ForwardIteratorConcept
{
@@ -479,8 +533,12 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
__function_requires< _ConvertibleConcept<
typename std::iterator_traits<_Tp>::iterator_category,
std::forward_iterator_tag> >();
+ __function_requires< _ForwardIteratorReferenceConcept<_Tp> >();
+ _Tp& __j = ++__i;
+ const _Tp& __k = __i++;
typedef typename std::iterator_traits<_Tp>::reference _Ref;
- _Ref __r _IsUnused = *__i;
+ _Ref __r = *__k;
+ _Ref __r2 = *__i++;
}
_Tp __i;
};
@@ -490,7 +548,9 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
{
void __constraints() {
__function_requires< _ForwardIteratorConcept<_Tp> >();
- *__i++ = *__i; // require postincrement and assignment
+ typedef typename std::iterator_traits<_Tp>::reference _Ref;
+ typedef typename std::iterator_traits<_Tp>::value_type _Val;
+ __function_requires< _Mutable_ForwardIteratorReferenceConcept<_Tp> >();
}
_Tp __i;
};
@@ -503,8 +563,10 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
__function_requires< _ConvertibleConcept<
typename std::iterator_traits<_Tp>::iterator_category,
std::bidirectional_iterator_tag> >();
- --__i; // require predecrement operator
- __i--; // require postdecrement operator
+ _Tp& __j = --__i; // require predecrement operator
+ const _Tp& __k = __i--; // require postdecrement operator
+ typedef typename std::iterator_traits<_Tp>::reference _Ref;
+ _Ref __r = *__j--;
}
_Tp __i;
};
@@ -515,7 +577,6 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
void __constraints() {
__function_requires< _BidirectionalIteratorConcept<_Tp> >();
__function_requires< _Mutable_ForwardIteratorConcept<_Tp> >();
- *__i-- = *__i; // require postdecrement and assignment
}
_Tp __i;
};
@@ -530,16 +591,15 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
__function_requires< _ConvertibleConcept<
typename std::iterator_traits<_Tp>::iterator_category,
std::random_access_iterator_tag> >();
- // ??? We don't use _Ref, are we just checking for "referenceability"?
typedef typename std::iterator_traits<_Tp>::reference _Ref;
- __i += __n; // require assignment addition operator
+ _Tp& __j = __i += __n; // require assignment addition operator
__i = __i + __n; __i = __n + __i; // require addition with difference type
- __i -= __n; // require assignment subtraction op
+ _Tp& __k = __i -= __n; // require assignment subtraction op
__i = __i - __n; // require subtraction with
// difference type
__n = __i - __j; // require difference operator
- (void)__i[__n]; // require element access operator
+ _Ref __r = __i[__n]; // require element access operator
}
_Tp __a, __b;
_Tp __i, __j;
@@ -552,12 +612,13 @@ struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
void __constraints() {
__function_requires< _RandomAccessIteratorConcept<_Tp> >();
__function_requires< _Mutable_BidirectionalIteratorConcept<_Tp> >();
- __i[__n] = *__i; // require element access and assignment
}
_Tp __i;
typename std::iterator_traits<_Tp>::difference_type __n;
};
+#pragma GCC diagnostic pop
+
//===========================================================================
// Container Concepts
diff --git a/libstdc++-v3/testsuite/24_iterators/operations/prev_neg.cc b/libstdc++-v3/testsuite/24_iterators/operations/prev_neg.cc
index cafafc4b651..d22491999a8 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 *-*-* } 223 }
+ // { dg-error "forward_iterator" "" { target *-*-* } 231 }
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-09-28 19:26 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-28 19:26 [committed] libstdc++: Fix concept checks for iterators Jonathan Wakely
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).