On Fri, Oct 2, 2026 at 7:06 AM 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;
>
I meant:
              static const size_t _S_local =  _Nb * sizeof(_CharT) <= 256 ?
_Nb : 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