public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
From: Jonathan Wakely <redi@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org
Subject: [gcc r12-5552] libstdc++: Fix trivial relocation for constexpr std::vector
Date: Fri, 26 Nov 2021 23:07:47 +0000 (GMT)	[thread overview]
Message-ID: <20211126230747.2925E3857C4C@sourceware.org> (raw)

https://gcc.gnu.org/g:33adfd0d42e54c809b0c53212abe66e8c874b2f8

commit r12-5552-g33adfd0d42e54c809b0c53212abe66e8c874b2f8
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Nov 26 21:34:17 2021 +0000

    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.

Diff:
---
 libstdc++-v3/include/bits/stl_uninitialized.h | 45 ++++++++++++++++++---------
 libstdc++-v3/include/bits/stl_vector.h        |  4 ---
 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 673f6a07675..f2786c5a461 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 bd15b6bd8a8..4587757637e 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.


                 reply	other threads:[~2021-11-26 23:07 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211126230747.2925E3857C4C@sourceware.org \
    --to=redi@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    --cc=libstdc++-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).