This looks to have been wrong since r0-125454-gea89b2482f97aa which
introduced the predefined_ops.h. Since that change, the binary predicate
passed to std::__unique_copy is _Iter_comp_iter, which takes arguments
of the iterator type, not the iterator's value type.

This removes the checks from the __unique_copy overloads and moves them
into the second overload of std::unique_copy, where we have the original
binary predicate, not the adapted one from predefined_ops.h.

The third __unique_copy overload currently checks that the predicate is
callable with the input range value type and the output range value
type. This change alters that, so that we only ever check that the
predicate can be called with two arguments of the same type. That is
intentional, because calling the predicate with different types is a bug
that will be fixed in a later commit (see PR libstdc++/120386).

libstdc++-v3/ChangeLog:

        PR libstdc++/120384
        * include/bits/stl_algo.h (__unique_copy): Remove all
        _BinaryPredicateConcept concept checks.
        (unique_copy): Check _BinaryPredicateConcept in overload that
        takes a predicate.
        * testsuite/25_algorithms/unique_copy/120384.cc: New test.
---

Tested x86_64-linux.

 libstdc++-v3/include/bits/stl_algo.h            | 17 +++--------------
 .../25_algorithms/unique_copy/120384.cc         | 12 ++++++++++++
 2 files changed, 15 insertions(+), 14 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/25_algorithms/unique_copy/120384.cc

diff --git a/libstdc++-v3/include/bits/stl_algo.h 
b/libstdc++-v3/include/bits/stl_algo.h
index 71ead103d2bf..f5361aeab7e2 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -932,11 +932,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                  _OutputIterator __result, _BinaryPredicate __binary_pred,
                  forward_iterator_tag, output_iterator_tag)
     {
-      // concept requirements -- iterators already checked
-      __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
-         typename iterator_traits<_ForwardIterator>::value_type,
-         typename iterator_traits<_ForwardIterator>::value_type>)
-
       _ForwardIterator __next = __first;
       *__result = *__first;
       while (++__next != __last)
@@ -962,11 +957,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                  _OutputIterator __result, _BinaryPredicate __binary_pred,
                  input_iterator_tag, output_iterator_tag)
     {
-      // concept requirements -- iterators already checked
-      __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
-         typename iterator_traits<_InputIterator>::value_type,
-         typename iterator_traits<_InputIterator>::value_type>)
-
       typename iterator_traits<_InputIterator>::value_type __value = *__first;
       __decltype(__gnu_cxx::__ops::__iter_comp_val(__binary_pred))
        __rebound_pred
@@ -995,10 +985,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                  _ForwardIterator __result, _BinaryPredicate __binary_pred,
                  input_iterator_tag, forward_iterator_tag)
     {
-      // concept requirements -- iterators already checked
-      __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
-         typename iterator_traits<_ForwardIterator>::value_type,
-         typename iterator_traits<_InputIterator>::value_type>)
       *__result = *__first;
       while (++__first != __last)
        if (!__binary_pred(__result, __first))
@@ -4505,6 +4491,9 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
       __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
            typename iterator_traits<_InputIterator>::value_type>)
       __glibcxx_requires_valid_range(__first, __last);
+      __glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
+         typename iterator_traits<_InputIterator>::value_type,
+         typename iterator_traits<_InputIterator>::value_type>)
 
       if (__first == __last)
        return __result;
diff --git a/libstdc++-v3/testsuite/25_algorithms/unique_copy/120384.cc 
b/libstdc++-v3/testsuite/25_algorithms/unique_copy/120384.cc
new file mode 100644
index 000000000000..27cd3375acae
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/unique_copy/120384.cc
@@ -0,0 +1,12 @@
+// { dg-options "-D_GLIBCXX_CONCEPT_CHECKS" }
+// { dg-do compile }
+
+// PR 120384 _BinaryPredicateConcept checks in std::unique_copy are wrong
+
+#include <algorithm>
+
+void
+test_pr120384(const int* first, const int* last, int* out)
+{
+  std::unique_copy(first, last, out);
+}
-- 
2.49.0

Reply via email to