]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Fix allocator propagation for rvalue+rvalue string concatenation
authorJonathan Wakely <jwakely@redhat.com>
Mon, 28 Apr 2025 13:31:04 +0000 (14:31 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Tue, 29 Apr 2025 09:52:47 +0000 (10:52 +0100)
I made a last-minute change to Nina's r10-200-gf4e678ef74b272
implementation of P1165R1 (consistent allocator propagation for
operator+ on strings), so that the rvalue+rvalue case assumes that COW
strings do not support stateful allocators. I don't think that was true
when the change went in, and isn't true now. COW strings don't support
allocator propagation on assignment and swap, but they do support
non-equal stateful allocators, which are correctly propagated on move
construction.

This removes the preprocessor conditional in the rvalue+rvalue overload
so that COW strings are handled equivalently. Also use constexpr-if
unconditionally, disabling diagnostics with pragmas.

libstdc++-v3/ChangeLog:

* include/bits/basic_string.h (operator+(string&&, string&&)):
Do not assume that COW strings have equal allocators. Use
constexpr-if unconditionally.
* testsuite/21_strings/basic_string/allocator/char/operator_plus.cc:
Remove cxx11_abi effective-target check.
* testsuite/21_strings/basic_string/allocator/wchar_t/operator_plus.cc:
Likewise.

Reviewed-by: Tomasz KamiƄski <tkaminsk@redhat.com>
libstdc++-v3/include/bits/basic_string.h
libstdc++-v3/testsuite/21_strings/basic_string/allocator/char/operator_plus.cc
libstdc++-v3/testsuite/21_strings/basic_string/allocator/wchar_t/operator_plus.cc

index c90bd099b6391b85533c9140d74441f55ac248ef..a087e637805546530ed11b95e26e5d5db10a257e 100644 (file)
@@ -3938,21 +3938,23 @@ _GLIBCXX_END_NAMESPACE_CXX11
     operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
              basic_string<_CharT, _Traits, _Alloc>&& __rhs)
     {
-#if _GLIBCXX_USE_CXX11_ABI
-      using _Alloc_traits = allocator_traits<_Alloc>;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr
+      // Return value must use __lhs.get_allocator(), but if __rhs has equal
+      // allocator then we can choose which parameter to modify in-place.
       bool __use_rhs = false;
-      if _GLIBCXX17_CONSTEXPR (typename _Alloc_traits::is_always_equal{})
+      if constexpr (allocator_traits<_Alloc>::is_always_equal::value)
        __use_rhs = true;
       else if (__lhs.get_allocator() == __rhs.get_allocator())
        __use_rhs = true;
       if (__use_rhs)
-#endif
        {
          const auto __size = __lhs.size() + __rhs.size();
          if (__size > __lhs.capacity() && __size <= __rhs.capacity())
            return std::move(__rhs.insert(0, __lhs));
        }
       return std::move(__lhs.append(__rhs));
+#pragma GCC diagnostic pop
     }
 
   template<typename _CharT, typename _Traits, typename _Alloc>
index 571f853517617bd591cbef00fe77e2b25c0a32ad..92e05690b193440384cbe5b7e89a2d32a7b721c2 100644 (file)
@@ -17,8 +17,6 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do run { target c++11 } }
-// COW strings don't support C++11 allocator propagation:
-// { dg-require-effective-target cxx11_abi }
 
 #include <string>
 #include <testsuite_hooks.h>
index 0da684360ab1b8561097ce69d3a7925107cc529b..b75b26ae85ce79a35839fdd5121300ff9a2feaa5 100644 (file)
@@ -17,8 +17,6 @@
 // <http://www.gnu.org/licenses/>.
 
 // { dg-do run { target c++11 } }
-// COW strings don't support C++11 allocator propagation:
-// { dg-require-effective-target cxx11_abi }
 
 #include <string>
 #include <testsuite_hooks.h>