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-5343] libstdc++: Set active member of union in std::string [PR103295] Date: Wed, 17 Nov 2021 17:23:02 +0000 (GMT) [thread overview] Message-ID: <20211117172302.B92983858D28@sourceware.org> (raw) https://gcc.gnu.org/g:6afa1083c6ee7b31629fb0c16299b952cb17868c commit r12-5343-g6afa1083c6ee7b31629fb0c16299b952cb17868c Author: Jonathan Wakely <jwakely@redhat.com> Date: Wed Nov 17 10:23:14 2021 +0000 libstdc++: Set active member of union in std::string [PR103295] Clang diagnoses that the new constexpr std::string constructors are not usable in constant expressions, because they start to write to members of the union without setting an active member. This adds a new helper function which returns the address of the local buffer after making it the active member. This doesn't fix all problems with Clang, because it still refuses to write to memory returned by the allocator. libstdc++-v3/ChangeLog: PR libstdc++/103295 * include/bits/basic_string.h (_M_use_local_data()): New member function to make local buffer the active member. (assign(const basic_string&)): Use it. * include/bits/basic_string.tcc (_M_construct, reserve()): Likewise. Diff: --- libstdc++-v3/include/bits/basic_string.h | 15 ++++++++++++++- libstdc++-v3/include/bits/basic_string.tcc | 10 ++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h index 0b7d6c0a981..9d281f5daf2 100644 --- a/libstdc++-v3/include/bits/basic_string.h +++ b/libstdc++-v3/include/bits/basic_string.h @@ -325,6 +325,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 _M_get_allocator() const { return _M_dataplus; } + // Ensure that _M_local_buf is the active member of the union. + __attribute__((__always_inline__)) + _GLIBCXX14_CONSTEXPR + pointer + _M_use_local_data() _GLIBCXX_NOEXCEPT + { +#if __cpp_lib_is_constant_evaluated + if (__builtin_is_constant_evaluated()) + _M_local_buf[0] = _CharT(); +#endif + return _M_local_data(); + } + private: #ifdef _GLIBCXX_DISAMBIGUATE_REPLACE_INST @@ -1487,7 +1500,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 if (__str.size() <= _S_local_capacity) { _M_destroy(_M_allocated_capacity); - _M_data(_M_local_data()); + _M_data(_M_use_local_data()); _M_set_length(0); } else diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc index 5743770b42a..5a51f7e21b5 100644 --- a/libstdc++-v3/include/bits/basic_string.tcc +++ b/libstdc++-v3/include/bits/basic_string.tcc @@ -170,9 +170,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION size_type __len = 0; size_type __capacity = size_type(_S_local_capacity); + pointer __p = _M_use_local_data(); + while (__beg != __end && __len < __capacity) { - _M_data()[__len++] = *__beg; + __p[__len++] = *__beg; ++__beg; } @@ -223,6 +225,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_data(_M_create(__dnew, size_type(0))); _M_capacity(__dnew); } + else + _M_use_local_data(); // Check for out_of_range and length_error exceptions. __try @@ -247,6 +251,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_data(_M_create(__n, size_type(0))); _M_capacity(__n); } + else + _M_use_local_data(); if (__n) this->_S_assign(_M_data(), __n, __c); @@ -355,7 +361,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__length <= size_type(_S_local_capacity)) { - this->_S_copy(_M_local_data(), _M_data(), __length + 1); + this->_S_copy(_M_use_local_data(), _M_data(), __length + 1); _M_destroy(__capacity); _M_data(_M_local_data()); }
reply other threads:[~2021-11-17 17:23 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=20211117172302.B92983858D28@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: linkBe 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).