diff mbox series

[committed] libstdc++: Fix BUILTIN-PTR-CMP helpers

Message ID 20200209135626.GA1239883@redhat.com
State New
Headers show
Series [committed] libstdc++: Fix BUILTIN-PTR-CMP helpers | expand

Commit Message

Jonathan Wakely Feb. 9, 2020, 1:56 p.m. UTC
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.

Tested powerpc64le-linux, committed to master.
commit dcda050e6c3c3726cb14109674053f83cae330be
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Sun Feb 9 13:37:43 2020 +0000

    libstdc++: Fix BUILTIN-PTR-CMP helpers
    
    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.

Comments

Jonathan Wakely Feb. 9, 2020, 2:02 p.m. UTC | #1
On 09/02/20 13:56 +0000, Jonathan Wakely wrote:
>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.

This fixes the new comments I added to those tests.

Tested x86_64-linux, committed to master.
diff mbox series

Patch

diff --git a/libstdc++-v3/include/bits/range_cmp.h b/libstdc++-v3/include/bits/range_cmp.h
index e0385035543..571ba7f9555 100644
--- a/libstdc++-v3/include/bits/range_cmp.h
+++ b/libstdc++-v3/include/bits/range_cmp.h
@@ -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)); }
diff --git a/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/equal_to.cc b/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/equal_to.cc
index 39bc984c508..34f8ee5aca4 100644
--- a/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/equal_to.cc
+++ b/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/equal_to.cc
@@ -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()
 {
diff --git a/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/less.cc b/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/less.cc
index 978894d5fc0..bf7d600e7fe 100644
--- a/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/less.cc
+++ b/libstdc++-v3/testsuite/20_util/function_objects/range.cmp/less.cc
@@ -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()
 {