From dcda050e6c3c3726cb14109674053f83cae330be Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Sun, 9 Feb 2020 13:37:43 +0000 Subject: [PATCH] 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. --- libstdc++-v3/ChangeLog | 9 +++++++++ libstdc++-v3/include/bits/range_cmp.h | 6 ++++-- .../20_util/function_objects/range.cmp/equal_to.cc | 9 +++++++++ .../testsuite/20_util/function_objects/range.cmp/less.cc | 9 +++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 1781e63f1cc..fb4641aee6d 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,12 @@ +2020-02-09 Jonathan Wakely + + * 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 * 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 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 concept __eq_builtin_ptr_cmp - = convertible_to<_Tp, const volatile void*> + = requires (_Tp&& __t, _Up&& __u) { { __t == __u } -> same_as; } + && 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 concept __less_builtin_ptr_cmp - = convertible_to<_Tp, const volatile void*> + = requires (_Tp&& __t, _Up&& __u) { { __t < __u } -> same_as; } + && 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 ); + 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 ); + int main() { -- 2.30.2