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

Reply via email to