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 >> >>
