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; }
 
        explicit _Buffer(_CharT* __p) : _M_ptr(__p) { }
 
@@ -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());
       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