[PATCH] libstdc++: Fix bogus use of memcmp in ranges::lexicographical_compare (PR 93972)
Christophe Lyon
christophe.lyon@linaro.org
Mon Mar 2 12:23:00 GMT 2020
On Fri, 28 Feb 2020 at 22:53, Jonathan Wakely <jwakely@redhat.com> wrote:
>
> On 28/02/20 14:59 -0500, Patrick Palka wrote:
> >We were enabling the memcmp optimization in ranges::lexicographical_compare for
> >signed integral types and for integral types larger than a byte. But memcmp
> >gives the wrong answer for arrays of such types. This patch fixes this issue by
> >refining the condition that enables the memcmp optimization. It's now
> >consistent with the corresponding condition used in
> >std::lexicographical_compare.
> >
> >libstdc++-v3/ChangeLog:
> >
> > PR libstdc++/93972
> > * include/bits/ranges_algo.h (__lexicographical_compare_fn::operator()):
> > Fix condition for when to use memcmp, making it consistent with the
> > corresponding condition used in std::lexicographical_compare.
> > * testsuite/25_algorithms/lexicographical_compare/93972.cc: New test.
Hi,
The new test fails on aarch64 and arm, and other targets according to
gcc-testresults.
On aarch64, my log says:
FAIL: 25_algorithms/lexicographical_compare/93972.cc (test for excess errors)
Excess errors:
/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-aarch64-none-linux-gnu/gcc3/aarch64-none-linux-gnu/libstdc++-v3/include/bits/ranges_algo.h:3490:
error: no matching function for call to '__memcmp(char*&, unsigned
char*&, const long int&)'
/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-aarch64-none-linux-gnu/gcc3/aarch64-none-linux-gnu/libstdc++-v3/include/bits/ranges_algo.h:3490:
error: no matching function for call to '__memcmp(char*&, unsigned
char*&, const long int&)'
/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-aarch64-none-linux-gnu/gcc3/aarch64-none-linux-gnu/libstdc++-v3/include/bits/ranges_algo.h:3490:
error: no matching function for call to '__memcmp(unsigned char*&,
char*&, const long int&)'
/aci-gcc-fsf/builds/gcc-fsf-gccsrc/obj-aarch64-none-linux-gnu/gcc3/aarch64-none-linux-gnu/libstdc++-v3/include/bits/ranges_algo.h:3490:
error: no matching function for call to '__memcmp(unsigned char*&,
char*&, const long int&)'
UNRESOLVED: 25_algorithms/lexicographical_compare/93972.cc compilation
failed to produce executable
Christophe
> >---
> > libstdc++-v3/include/bits/ranges_algo.h | 8 +-
> > .../lexicographical_compare/93972.cc | 169 ++++++++++++++++++
> > 2 files changed, 175 insertions(+), 2 deletions(-)
> > create mode 100644 libstdc++-v3/testsuite/25_algorithms/lexicographical_compare/93972.cc
> >
> >diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h
> >index 05c0851d411..8fa4a8a9161 100644
> >--- a/libstdc++-v3/include/bits/ranges_algo.h
> >+++ b/libstdc++-v3/include/bits/ranges_algo.h
> >@@ -3466,9 +3466,13 @@ namespace ranges
> > {
> > using _ValueType1 = iter_value_t<_Iter1>;
> > using _ValueType2 = iter_value_t<_Iter2>;
> >+ // This condition is consistent with the one in
> >+ // __lexicographical_compare_aux in <bits/stl_algobase.h>.
> > constexpr bool __use_memcmp
> >- = ((is_integral_v<_ValueType1> || is_pointer_v<_ValueType1>)
> >- && is_same_v<_ValueType1, _ValueType2>
> >+ = (__is_byte<_ValueType1>::__value
> >+ && __is_byte<_ValueType2>::__value
> >+ && !__gnu_cxx::__numeric_traits<_ValueType1>::__is_signed
> >+ && !__gnu_cxx::__numeric_traits<_ValueType2>::__is_signed
>
> I think this could be:
>
> && !is_signed_v<_ValueType1>
> && !is_signed_v<_ValueType2>
>
> because this code doesn't need to be valid for C++98. But on the other
> hand, there's value in being consistent with the condition in
> std::lexicographical_compare.
>
> OK for master, thanks for the quick fix.
>
More information about the Libstdc++
mailing list