libstdc++: Fix BUILTIN-PTR-CMP helpers
authorJonathan Wakely <jwakely@redhat.com>
Sun, 9 Feb 2020 13:37:43 +0000 (13:37 +0000)
committerJonathan Wakely <jwakely@redhat.com>
Sun, 9 Feb 2020 13:37:43 +0000 (13:37 +0000)
The helpers that implement BUILTIN-PTR-CMP do not currently check if the
arguments are actually comparable, so the concept is true when it
shouldn't be.

Since we're trying to test for an unambiguous conversion to pointers, we
can also require that it returns bool, because the built-in comparisons
for pointers do return bool.

* include/bits/range_cmp.h (__detail::__eq_builtin_ptr_cmp): Require
equality comparison to be valid and return bool.
(__detail::__less_builtin_ptr_cmp): Likewise for less-than comparison.
* testsuite/20_util/function_objects/range.cmp/equal_to.cc: Check
type with ambiguous conversion to fundamental types.
* testsuite/20_util/function_objects/range.cmp/less.cc: Likewise.

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/range_cmp.h
libstdc++-v3/testsuite/20_util/function_objects/range.cmp/equal_to.cc
libstdc++-v3/testsuite/20_util/function_objects/range.cmp/less.cc

index 1781e63f1ccbb2d3c34a0bfd9105f5fd5220e146..fb4641aee6dd994cdf5cf8c6e5c27c783365c3f3 100644 (file)
@@ -1,3 +1,12 @@
+2020-02-09  Jonathan Wakely  <jwakely@redhat.com>
+
+       * include/bits/range_cmp.h (__detail::__eq_builtin_ptr_cmp): Require
+       equality comparison to be valid and return bool.
+       (__detail::__less_builtin_ptr_cmp): Likewise for less-than comparison.
+       * testsuite/20_util/function_objects/range.cmp/equal_to.cc: Check
+       type with ambiguous conversion to fundamental types.
+       * testsuite/20_util/function_objects/range.cmp/less.cc: Likewise.
+
 2020-02-07  Jonathan Wakely  <jwakely@redhat.com>
 
        * include/bits/iterator_concepts.h (iter_difference_t, iter_value_t):
index e03850355437650dda18e8ebac87f02e9bd1b786..571ba7f955510616e5ebee332b8392c669b31f00 100644 (file)
@@ -62,7 +62,8 @@ namespace ranges
     // BUILTIN-PTR-CMP(T, ==, U)
     template<typename _Tp, typename _Up>
       concept __eq_builtin_ptr_cmp
-       = convertible_to<_Tp, const volatile void*>
+       = requires (_Tp&& __t, _Up&& __u) { { __t == __u } -> same_as<bool>; }
+         && convertible_to<_Tp, const volatile void*>
          && convertible_to<_Up, const volatile void*>
          && (! requires(_Tp&& __t, _Up&& __u)
              { operator==(std::forward<_Tp>(__t), std::forward<_Up>(__u)); }
@@ -73,7 +74,8 @@ namespace ranges
     // BUILTIN-PTR-CMP(T, <, U)
     template<typename _Tp, typename _Up>
       concept __less_builtin_ptr_cmp
-       = convertible_to<_Tp, const volatile void*>
+       = requires (_Tp&& __t, _Up&& __u) { { __t < __u } -> same_as<bool>; }
+         && convertible_to<_Tp, const volatile void*>
          && convertible_to<_Up, const volatile void*>
          && (! requires(_Tp&& __t, _Up&& __u)
              { operator<(std::forward<_Tp>(__t), std::forward<_Up>(__u)); }
index 39bc984c5082cca947206428a5a9145908797441..34f8ee5aca4e9d4f6e3eb49f058de57d690a4f4b 100644 (file)
@@ -69,6 +69,15 @@ test02()
   VERIFY( f(x, x) );
 }
 
+struct Y
+{
+  operator void*() const;
+  operator int() const;
+};
+
+// X{} == X{} is ambiguous so ranges::equal_to{}(X{}, X{}) should be invalid
+static_assert( !std::is_invocable_v<F&, Y, Y> );
+
 int
 main()
 {
index 978894d5fc0ceda5d9e4bb2352c55dcc0404a5fa..bf7d600e7fea71530d903c92e0adc4d8e085f34c 100644 (file)
@@ -74,6 +74,15 @@ test02()
   VERIFY( ! f(x, x) );
 }
 
+struct Y
+{
+  operator void*() const;
+  operator int() const;
+};
+
+// X{} == X{} is ambiguous so ranges::less{}(X{}, X{}) should be invalid
+static_assert( !std::is_invocable_v<F&, Y, Y> );
+
 int
 main()
 {