[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