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? Does not
matter with my proposal,
as we will create array of _CharT on stack.

>        else
>         __ptr = new _CharT[_Nb];
>        const _Buffer __buf(__ptr);
> diff --git a/libstdc++-v3/testsuite/20_util/bitset/io/wchar_t.cc
> b/libstdc++-v3/testsuite/20_util/bitset/io/wchar_t.cc
> new file mode 100644
> index 000000000000..893ebd37352a
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/20_util/bitset/io/wchar_t.cc
> @@ -0,0 +1,36 @@
> +// { dg-do run }
> +
> +// C++98 23.3.5.3 bitset operators
> +
> +#include <bitset>
> +#include <sstream>
> +#include <testsuite_hooks.h>
> +
> +// Bug 124370 - Out-of-bounds write for wistream >> bitset
> +void
> +test_pr124370()
> +{
> +  std::wistringstream input(L"10011011001101");
> +  std::bitset<10> b;
> +  input >> b;
> +  VERIFY( b == std::bitset<10>(0b1001101100) );
> +}
> +
> +// Round-trip through a wide stream.
> +template<int N>
> +void
> +test_round_trip()
> +{
> +  std::bitset<N> a(0b100110110011010101101010), b;
> +  std::wstringstream ss;
> +  ss << a;
> +  ss >> b;
> +  VERIFY( b == a );
> +}
> +
> +int main()
> +{
> +  test_pr124370();
> +  test_round_trip<24>();
> +  test_round_trip<1024>();
> +}
> --
> 2.55.0
>
>

Reply via email to