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:
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();