diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h index 4eba053ac75..94a79b85d15 100644 --- a/libstdc++-v3/include/bits/stl_algobase.h +++ b/libstdc++-v3/include/bits/stl_algobase.h @@ -83,27 +83,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ template _GLIBCXX14_CONSTEXPR - inline void* - __memmove(_Tp* __dst, const _Tp* __src, size_t __num) + inline void + __memmove(_Tp* __dst, const _Tp* __src, ptrdiff_t __num) { #ifdef __cpp_lib_is_constant_evaluated if (std::is_constant_evaluated()) { - for(; __num > 0; --__num) + __dst += __num; + __src += __num; + for (; __num != 0; --__num) { if constexpr (_IsMove) - *__dst = std::move(*__src); + *--__dst = std::move(*--__src); else - *__dst = *__src; - ++__src; - ++__dst; + *--__dst = *--__src; } - return __dst; } else #endif - return __builtin_memmove(__dst, __src, sizeof(_Tp) * __num); - return __dst; + __builtin_memmove(__dst, __src, sizeof(_Tp) * __num); } /* @@ -730,12 +728,6 @@ _GLIBCXX_END_NAMESPACE_CONTAINER && __is_pointer<_BI2>::__value && __are_same<_ValueType1, _ValueType2>::__value); -#ifdef __cpp_lib_is_constant_evaluated - if (std::is_constant_evaluated()) - return std::__copy_move_backward::__copy_move_b(__first, __last, - __result); -#endif return std::__copy_move_backward<_IsMove, __simple, _Category>::__copy_move_b(__first, __last, diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/copy/constexpr.cc index 67910b8773e..fc70db6dae7 100644 --- a/libstdc++-v3/testsuite/25_algorithms/copy/constexpr.cc +++ b/libstdc++-v3/testsuite/25_algorithms/copy/constexpr.cc @@ -22,14 +22,25 @@ #include constexpr bool -test() +test1() { - constexpr std::array ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}; + constexpr std::array ca0{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; std::array ma0{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; const auto out6 = std::copy(ca0.begin(), ca0.begin() + 8, ma0.begin() + 2); - return out6 == ma0.begin() + 10; + return out6 == ma0.begin() + 10 && *(ma0.begin() + 2) == 1 && *out6 == 0; } -static_assert(test()); +static_assert(test1()); + +constexpr bool +test2() +{ + std::array ma0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}; + const auto out6 = std::copy(ma0.begin(), ma0.begin() + 8, ma0.begin() + 2); + + return out6 == ma0.begin() + 10 && *(ma0.begin() + 9) == 7; +} + +static_assert(test2()); diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/constexpr_neg.cc b/libstdc++-v3/testsuite/25_algorithms/copy/constexpr_neg.cc new file mode 100644 index 00000000000..49052467409 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy/constexpr_neg.cc @@ -0,0 +1,38 @@ +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a xfail *-*-* } } + +#include +#include + +constexpr bool +test() +{ + constexpr std::array ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}; + std::array ma0{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; + + const auto out6 = std::copy(ca0.begin() + 8, ca0.begin(), ma0.begin() + 2); + + return out6 == ma0.begin() + 10; +} + +static_assert(test()); // { dg-error "outside the bounds" } + +// { dg-prune-output "non-constant condition" } +// { dg-prune-output "in 'constexpr'" } diff --git a/libstdc++-v3/testsuite/25_algorithms/copy_backward/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/copy_backward/constexpr.cc index ed7487905a8..c0e1a747832 100644 --- a/libstdc++-v3/testsuite/25_algorithms/copy_backward/constexpr.cc +++ b/libstdc++-v3/testsuite/25_algorithms/copy_backward/constexpr.cc @@ -22,15 +22,27 @@ #include constexpr bool -test() +test1() { - constexpr std::array ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}; + constexpr std::array ca0{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}; std::array ma0{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; const auto out7 = std::copy_backward(ca0.begin(), ca0.begin() + 8, ma0.begin() + 10); - return true; + return out7 == ma0.begin() + 2 && *out7 == 1 && *(ma0.begin() + 10) == 0; } -static_assert(test()); +static_assert(test1()); + +constexpr bool +test2() +{ + std::array ma0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}; + const auto out7 = std::copy_backward(ma0.begin(), ma0.begin() + 8, + ma0.begin() + 10); + + return out7 == ma0.begin() + 2 && *out7 == 0 && *(ma0.begin() + 9) == 7; +} + +static_assert(test2()); diff --git a/libstdc++-v3/testsuite/25_algorithms/copy_backward/constexpr_neg.cc b/libstdc++-v3/testsuite/25_algorithms/copy_backward/constexpr_neg.cc new file mode 100644 index 00000000000..3dc595d239f --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy_backward/constexpr_neg.cc @@ -0,0 +1,39 @@ +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a xfail *-*-* } } + +#include +#include + +constexpr bool +test() +{ + constexpr std::array ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}; + std::array ma0{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; + + const auto out7 = std::copy_backward(ca0.begin() + 8, ca0.begin(), + ma0.begin() + 10); + + return out7 == ma0.begin() + 2; +} + +static_assert(test()); // { dg-error "outside the bounds" } + +// { dg-prune-output "non-constant condition" } +// { dg-prune-output "in 'constexpr'" }