On Fri, Oct 2, 2026 at 10:26 AM Jonathan Wakely <[email protected]> wrote:
> On Fri, 2 Oct 2026 at 09:12, Jonathan Wakely <[email protected]> wrote: > > > > On Fri, 2 Oct 2026 at 06:06, Tomasz Kaminski <[email protected]> > wrote: > > > > > > > > > > > > On Fri, Oct 2, 2026 at 12:05 AM Jonathan Wakely <[email protected]> > wrote: > > >> > > >> Fix the __builtin_alloca argument to account for wide characters. Also > > >> consider them when deciding whether to use alloca or the heap. > > >> > > >> libstdc++-v3/ChangeLog: > > >> > > >> PR libstdc++/124370 > > >> * include/std/bitset (operator>>): Account for sizeof(_CharT) > in > > >> condition and buffer size. > > >> * testsuite/20_util/bitset/io/wchar_t.cc: New test. > > >> --- > > >> > > >> Tested x86_64-linux. > > >> > > >> We previously had no tests for wide character I/O with bitset, so the > > >> new test covers the basics as well as the bug. > > >> > > >> This is a regression so needs to be backported. > > >> > > >> libstdc++-v3/include/std/bitset | 8 +++-- > > >> .../testsuite/20_util/bitset/io/wchar_t.cc | 36 > +++++++++++++++++++ > > >> 2 files changed, 42 insertions(+), 2 deletions(-) > > >> create mode 100644 > libstdc++-v3/testsuite/20_util/bitset/io/wchar_t.cc > > >> > > >> diff --git a/libstdc++-v3/include/std/bitset > b/libstdc++-v3/include/std/bitset > > >> index d581606e7dde..c244ee80bbb8 100644 > > >> --- a/libstdc++-v3/include/std/bitset > > >> +++ b/libstdc++-v3/include/std/bitset > > >> @@ -1709,7 +1709,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER > > >> #pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr > > >> struct _Buffer > > >> { > > >> - static _GLIBCXX_CONSTEXPR bool _S_use_alloca() { return _Nb > <= 256; } > > >> + static _GLIBCXX_CONSTEXPR size_t > > >> + _S_size_in_bytes() { return _Nb * sizeof(_CharT); } > > >> + > > >> + static _GLIBCXX_CONSTEXPR bool > > >> + _S_use_alloca() { return _S_size_in_bytes() <= 256; } > > > > > > I would prefer something like: > > > private: > > > static const size_t _S_local = _Nb * sizeof(_CharT) <= 256 > ? _S_bytes : 1; > > > _CharT _M_buf[_S_local]; > > > > > >> > > >> > > >> explicit _Buffer(_CharT* __p) : _M_ptr(__p) { } > > > > > > And then: > > > _Buffer() : _M_ptr(&__local) > > > { > > > if _GLIBCXX_CONSTEXPR(_S_local < _Nb) > > > _M_ptr = new _CharT[_Nb]; > > > } > > > > > > ~_Buffer() > > > { > > > if _GLIBCXX_CONSTEXPR(_S_local < _Nb) > > > delete[] _M_ptr; > > > } > > > > > >> > > >> @@ -1723,7 +1727,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER > > >> }; > > >> _CharT* __ptr; > > >> if _GLIBCXX_CONSTEXPR (_Buffer::_S_use_alloca()) > > >> - __ptr = (_CharT*)__builtin_alloca(_Nb); > > >> + __ptr = > (_CharT*)__builtin_alloca(_Buffer::_S_size_in_bytes()); > > > > > > Is this guaranteed to always give us proper aligment for wchar_t? > > > > "The object is aligned on the default stack alignment boundary for the > > target determined by the __BIGGEST_ALIGNMENT__ macro." > > > https://gcc.gnu.org/onlinedocs/gcc/Stack-Allocation.html#index-_005f_005fbuiltin_005falloca > > > > > Does not matter with my proposal, > > > as we will create array of _CharT on stack. > > > > Indeed > > We can do this to save a few more bytes on the stack, but maybe the > union is overkill: > I think it is overkill, 4B on stack is one temporaryr float. > > static const bool __use_local = _Nb * sizeof(_CharT) <= 256; > > struct _Buffer > { > #pragma GCC diagnostic push > #pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr > _Buffer() > { > if _GLIBCXX_CONSTEXPR (!__use_local) > _M_ptr = new _CharT[_Nb]; > } > > ~_Buffer() > { > if _GLIBCXX_CONSTEXPR (!__use_local) > delete[] _M_ptr; > } > > _CharT* get() > { > if _GLIBCXX_CONSTEXPR (!__use_local) > return _M_ptr; > else > return _M_local; > } > #pragma GCC diagnostic pop > > union { > _CharT* _M_ptr; > _CharT _M_local[__use_local ? _Nb : 1]; > }; > } __buf; > > _CharT* __ptr = __buf.get(); > >
