* [committed] libstdc++: Set active member of union in std::string [PR103295]
@ 2021-11-17 17:25 Jonathan Wakely
0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2021-11-17 17:25 UTC (permalink / raw)
To: libstdc++, gcc-patches
Tested powerpc64le-linux, pushed to trunk.
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.
---
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());
}
--
2.31.1
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-11-17 17:25 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-17 17:25 [committed] libstdc++: Set active member of union in std::string [PR103295] Jonathan Wakely
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).