aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2020-02-09 13:37:43 +0000
committerJonathan Wakely <jwakely@redhat.com>2020-02-09 13:37:43 +0000
commitdcda050e6c3c3726cb14109674053f83cae330be (patch)
tree57f505992990d92e97d0e99617c3f7cf7c7227b6
parent81958cd6adf402a85dc7d21b43caac56fba0af21 (diff)
downloadgcc-dcda050e6c3c3726cb14109674053f83cae330be.zip
gcc-dcda050e6c3c3726cb14109674053f83cae330be.tar.gz
gcc-dcda050e6c3c3726cb14109674053f83cae330be.tar.bz2
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.
-rw-r--r--libstdc++-v3/ChangeLog9
-rw-r--r--libstdc++-v3/include/bits/range_cmp.h6
-rw-r--r--libstdc++-v3/testsuite/20_util/function_objects/range.cmp/equal_to.cc9
-rw-r--r--libstdc++-v3/testsuite/20_util/function_objects/range.cmp/less.cc9
4 files changed, 31 insertions, 2 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 1781e63..fb4641a 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -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):
diff --git a/libstdc++-v3/include/bits/range_cmp.h b/libstdc++-v3/include/bits/range_cmp.h
index e038503..571ba7f 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 39bc984..34f8ee5 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 978894d..bf7d600 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()
{