aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2021-11-26 21:34:17 +0000
committerJonathan Wakely <jwakely@redhat.com>2021-11-26 22:28:48 +0000
commit33adfd0d42e54c809b0c53212abe66e8c874b2f8 (patch)
treef150053a0dfbd140fa6c9149d5fdea1d6b4f5e18
parent76c6be48b7841524974754f8ea7533b82c7de77e (diff)
downloadgcc-33adfd0d42e54c809b0c53212abe66e8c874b2f8.zip
gcc-33adfd0d42e54c809b0c53212abe66e8c874b2f8.tar.gz
gcc-33adfd0d42e54c809b0c53212abe66e8c874b2f8.tar.bz2
libstdc++: Fix trivial relocation for constexpr std::vector
When implementing constexpr std::vector I added a check for constant evaluation in vector::_S_use_relocate(), so that we would not try to relocate trivial objects by using memmove. But I put it in the constexpr function that decides whether to relocate or not, and calls to that function are always constant evaluated. This had the effect of disabling relocation entirely, even in non-constexpr vectors. This removes the check in _S_use_relocate() and modifies the actual relocation algorithm, __relocate_a_1, to use the non-trivial implementation instead of memmove when called during constant evaluation. libstdc++-v3/ChangeLog: * include/bits/stl_uninitialized.h (__relocate_a_1): Do not use memmove during constant evaluation. * include/bits/stl_vector.h (vector::_S_use_relocate()): Do not check is_constant_evaluated in always-constexpr function.
-rw-r--r--libstdc++-v3/include/bits/stl_uninitialized.h45
-rw-r--r--libstdc++-v3/include/bits/stl_vector.h4
2 files changed, 30 insertions, 19 deletions
diff --git a/libstdc++-v3/include/bits/stl_uninitialized.h b/libstdc++-v3/include/bits/stl_uninitialized.h
index 673f6a0..f2786c5 100644
--- a/libstdc++-v3/include/bits/stl_uninitialized.h
+++ b/libstdc++-v3/include/bits/stl_uninitialized.h
@@ -1051,6 +1051,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// @cond undocumented
template<typename _Tp, typename _Up, typename _Allocator>
+ _GLIBCXX20_CONSTEXPR
inline void
__relocate_object_a(_Tp* __restrict __dest, _Up* __restrict __orig,
_Allocator& __alloc)
@@ -1070,18 +1071,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __is_bitwise_relocatable
: is_trivial<_Tp> { };
- template <typename _Tp, typename _Up>
- _GLIBCXX20_CONSTEXPR
- inline __enable_if_t<std::__is_bitwise_relocatable<_Tp>::value, _Tp*>
- __relocate_a_1(_Tp* __first, _Tp* __last,
- _Tp* __result, allocator<_Up>&) noexcept
- {
- ptrdiff_t __count = __last - __first;
- if (__count > 0)
- __builtin_memmove(__result, __first, __count * sizeof(_Tp));
- return __result + __count;
- }
-
template <typename _InputIterator, typename _ForwardIterator,
typename _Allocator>
_GLIBCXX20_CONSTEXPR
@@ -1105,6 +1094,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __cur;
}
+ template <typename _Tp, typename _Up>
+ _GLIBCXX20_CONSTEXPR
+ inline __enable_if_t<std::__is_bitwise_relocatable<_Tp>::value, _Tp*>
+ __relocate_a_1(_Tp* __first, _Tp* __last,
+ _Tp* __result,
+ [[__maybe_unused__]] allocator<_Up>& __alloc) noexcept
+ {
+ ptrdiff_t __count = __last - __first;
+ if (__count > 0)
+ {
+#ifdef __cpp_lib_is_constant_evaluated
+ if (std::is_constant_evaluated())
+ {
+ // Can't use memmove. Wrap the pointer so that __relocate_a_1
+ // resolves to the non-trivial overload above.
+ __gnu_cxx::__normal_iterator<_Tp*, void> __out(__result);
+ __out = std::__relocate_a_1(__first, __last, __out, __alloc);
+ return __out.base();
+ }
+#endif
+ __builtin_memmove(__result, __first, __count * sizeof(_Tp));
+ }
+ return __result + __count;
+ }
+
+
template <typename _InputIterator, typename _ForwardIterator,
typename _Allocator>
_GLIBCXX20_CONSTEXPR
@@ -1115,9 +1130,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::__niter_base(__last),
std::__niter_base(__result), __alloc)))
{
- return __relocate_a_1(std::__niter_base(__first),
- std::__niter_base(__last),
- std::__niter_base(__result), __alloc);
+ return std::__relocate_a_1(std::__niter_base(__first),
+ std::__niter_base(__last),
+ std::__niter_base(__result), __alloc);
}
/// @endcond
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index bd15b6b..4587757 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -475,10 +475,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
static constexpr bool
_S_use_relocate()
{
-#if __cplusplus >= 202002L && __has_builtin(__builtin_is_constant_evaluated)
- if (__builtin_is_constant_evaluated())
- return false; // Cannot use memcpy in constant evaluation contexts.
-#endif
// Instantiating std::__relocate_a might cause an error outside the
// immediate context (in __relocate_object_a's noexcept-specifier),
// so only do it if we know the type can be move-inserted into *this.