This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[Patch] Substantive ostream bits of libstdc++/28277
- From: Paolo Carlini <pcarlini at suse dot de>
- To: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Date: Thu, 12 Oct 2006 12:34:33 +0200
- Subject: [Patch] Substantive ostream bits of libstdc++/28277
Hi,
the below fixes the actual testcases reported in the PR and now only the
arithmetic inserters remain to be fixed. The idea is simply outputting
padding chars and chars in the proper order, instead of constructing the
result in a temporary buffer (allocated on the stack). Something I like
about the fix solicited by the PR is that the work is done in a single
new _M_insert, which is reused for 6 different inserters overall, thus
reducing ostream.tcc to the minimal terms. The PR also prompted
implementing the proposed resolution of DR 586: I hope you all agree
with me that whereas not ready yet seems pretty straightforward,
otherwise we have to special case string inserters.
Tested x86/ia64-linux, will wait a while before going ahead (if people
prefer I can add the 2 new exports @3.4.10 instead of the current 3.4.9,
just let me know)
Paolo.
/////////////////
2006-10-12 Paolo Carlini <pcarlini@suse.de>
PR libstdc++/28277 (partial: ostream bits 2)
* include/std/std_ostream.h (basic_ostream<>::_M_insert(const
char_type*, streamsize)): New.
(basic_ostream<>::_M_write(char_type, streamsize)): Likewise.
(operator<<(basic_ostream<>&, _CharT), operator<<(basic_ostream<>&,
char), operator<<(basic_ostream<>&, const _CharT*),
operator<<(basic_ostream<>&, const char*)): Use the latter.
* include/bits/ostream.tcc (basic_ostream<>::_M_insert(const
char_type*, streamsize)): Define.
(operator<<(basic_ostream<>&, const char*)): Use the latter.
(operator<<(basic_ostream<>&, _CharT), operator<<(basic_ostream<>&,
char), operator<<(basic_ostream<>&, const _CharT*),
operator<<(basic_ostream<>&, const char*),
operator<<(basic_ostream<>&, const basic_string<>&)): Remove.
* include/bits/basic_string.h (operator<<(basic_ostream<>&,
const basic_string<>&)): Use the latter, implement DR 586.
* config/abi/pre/gnu.ver: Adjust, export the new _M_insert.
* docs/html/ext/howto.html: Add an entry for DR 586.
* testsuite/21_strings/basic_string/inserters_extractors/char/
28277.cc: New.
* testsuite/21_strings/basic_string/inserters_extractors/wchar_t/
28277.cc: Likewise.
* testsuite/27_io/basic_ostream/inserters_character/char/
28277-3.cc: Likewise.
* testsuite/27_io/basic_ostream/inserters_character/char/
28277-4.cc: Likewise.
* testsuite/27_io/basic_ostream/inserters_character/wchar_t/
28277-2.cc: Likewise.
* testsuite/27_io/basic_ostream/inserters_character/wchar_t/
28277-3.cc: Likewise.
* testsuite/27_io/basic_ostream/inserters_character/wchar_t/
28277-4.cc: Likewise.
Index: include/bits/basic_string.h
===================================================================
--- include/bits/basic_string.h (revision 117648)
+++ include/bits/basic_string.h (working copy)
@@ -2396,7 +2396,12 @@
template<typename _CharT, typename _Traits, typename _Alloc>
basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
- const basic_string<_CharT, _Traits, _Alloc>& __str);
+ const basic_string<_CharT, _Traits, _Alloc>& __str)
+ {
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 586. string inserter not a formatted function
+ return __os._M_insert(__str.data(), __str.size());
+ }
/**
* @brief Read a line from stream into a string.
Index: include/bits/ostream.tcc
===================================================================
--- include/bits/ostream.tcc (revision 117648)
+++ include/bits/ostream.tcc (working copy)
@@ -315,212 +315,63 @@
return *this;
}
- // 27.6.2.5.4 Character inserters.
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
- operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)
+ basic_ostream<_CharT, _Traits>::
+ _M_insert(const char_type* __s, streamsize __n)
{
- typedef basic_ostream<_CharT, _Traits> __ostream_type;
- typename __ostream_type::sentry __cerb(__out);
+ sentry __cerb(*this);
if (__cerb)
{
try
{
- const streamsize __w = __out.width();
- streamsize __len = 1;
- _CharT* __cs = &__c;
- if (__w > __len)
+ const streamsize __w = this->width();
+ if (__w > __n)
{
- __cs = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT)
- * __w));
- __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs,
- &__c, __w, __len, false);
- __len = __w;
+ const bool __left = ((this->flags() & ios_base::adjustfield)
+ == ios_base::left);
+ if (!__left)
+ _M_write(this->fill(), __w - __n);
+ if (this->good())
+ _M_write(__s, __n);
+ if (__left && this->good())
+ _M_write(this->fill(), __w - __n);
}
- __out._M_write(__cs, __len);
- __out.width(0);
+ else
+ _M_write(__s, __n);
+ this->width(0);
}
catch(...)
- { __out._M_setstate(ios_base::badbit); }
+ { this->_M_setstate(ios_base::badbit); }
}
- return __out;
+ return *this;
}
- // Specializations.
- template <class _Traits>
- basic_ostream<char, _Traits>&
- operator<<(basic_ostream<char, _Traits>& __out, char __c)
- {
- typedef basic_ostream<char, _Traits> __ostream_type;
- typename __ostream_type::sentry __cerb(__out);
- if (__cerb)
- {
- try
- {
- const streamsize __w = __out.width();
- streamsize __len = 1;
- char* __cs = &__c;
- if (__w > __len)
- {
- __cs = static_cast<char*>(__builtin_alloca(__w));
- __pad<char, _Traits>::_S_pad(__out, __out.fill(), __cs,
- &__c, __w, __len, false);
- __len = __w;
- }
- __out._M_write(__cs, __len);
- __out.width(0);
- }
- catch(...)
- { __out._M_setstate(ios_base::badbit); }
- }
- return __out;
- }
-
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
- operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)
- {
- typedef basic_ostream<_CharT, _Traits> __ostream_type;
- typename __ostream_type::sentry __cerb(__out);
- if (__cerb && __s)
- {
- try
- {
- const streamsize __w = __out.width();
- streamsize __len = static_cast<streamsize>(_Traits::length(__s));
- if (__w > __len)
- {
- _CharT* __cs = (static_cast<
- _CharT*>(__builtin_alloca(sizeof(_CharT)
- * __w)));
- __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs,
- __s, __w, __len, false);
- __s = __cs;
- __len = __w;
- }
- __out._M_write(__s, __len);
- __out.width(0);
- }
- catch(...)
- { __out._M_setstate(ios_base::badbit); }
- }
- else if (!__s)
- __out.setstate(ios_base::badbit);
- return __out;
- }
-
- template<typename _CharT, typename _Traits>
- basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)
{
- typedef basic_ostream<_CharT, _Traits> __ostream_type;
- // _GLIBCXX_RESOLVE_LIB_DEFECTS
- // 167. Improper use of traits_type::length()
- // Note that this is only in 'Review' status.
- typedef char_traits<char> __traits_type;
- typename __ostream_type::sentry __cerb(__out);
- if (__cerb && __s)
+ if (!__s)
+ __out.setstate(ios_base::badbit);
+ else
{
- _CharT* __ws = 0;
try
{
- const size_t __clen = __traits_type::length(__s);
- __ws = new _CharT[__clen];
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 167. Improper use of traits_type::length()
+ const size_t __clen = char_traits<char>::length(__s);
+ _CharT* __ws = new _CharT[__clen];
for (size_t __i = 0; __i < __clen; ++__i)
__ws[__i] = __out.widen(__s[__i]);
- _CharT* __str = __ws;
-
- const streamsize __w = __out.width();
- streamsize __len = static_cast<streamsize>(__clen);
- if (__w > __len)
- {
- _CharT* __cs = (static_cast<
- _CharT*>(__builtin_alloca(sizeof(_CharT)
- * __w)));
- __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs,
- __ws, __w, __len, false);
- __str = __cs;
- __len = __w;
- }
- __out._M_write(__str, __len);
- __out.width(0);
-
+ __out._M_insert(__ws, __clen);
delete [] __ws;
}
catch(...)
- {
- delete [] __ws;
- __out._M_setstate(ios_base::badbit);
- }
- }
- else if (!__s)
- __out.setstate(ios_base::badbit);
- return __out;
- }
-
- // Partial specializations.
- template<class _Traits>
- basic_ostream<char, _Traits>&
- operator<<(basic_ostream<char, _Traits>& __out, const char* __s)
- {
- typedef basic_ostream<char, _Traits> __ostream_type;
- typename __ostream_type::sentry __cerb(__out);
- if (__cerb && __s)
- {
- try
- {
- const streamsize __w = __out.width();
- streamsize __len = static_cast<streamsize>(_Traits::length(__s));
- if (__w > __len)
- {
- char* __cs = static_cast<char*>(__builtin_alloca(__w));
- __pad<char, _Traits>::_S_pad(__out, __out.fill(), __cs,
- __s, __w, __len, false);
- __s = __cs;
- __len = __w;
- }
- __out._M_write(__s, __len);
- __out.width(0);
- }
- catch(...)
{ __out._M_setstate(ios_base::badbit); }
}
- else if (!__s)
- __out.setstate(ios_base::badbit);
return __out;
}
- // 21.3.7.9 basic_string::operator<<
- template<typename _CharT, typename _Traits, typename _Alloc>
- basic_ostream<_CharT, _Traits>&
- operator<<(basic_ostream<_CharT, _Traits>& __out,
- const basic_string<_CharT, _Traits, _Alloc>& __str)
- {
- typedef basic_ostream<_CharT, _Traits> __ostream_type;
- typename __ostream_type::sentry __cerb(__out);
- if (__cerb)
- {
- const streamsize __w = __out.width();
- streamsize __len = static_cast<streamsize>(__str.size());
- const _CharT* __s = __str.data();
-
- // _GLIBCXX_RESOLVE_LIB_DEFECTS
- // 25. String operator<< uses width() value wrong
- if (__w > __len)
- {
- _CharT* __cs = (static_cast<
- _CharT*>(__builtin_alloca(sizeof(_CharT) * __w)));
- __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __cs, __s,
- __w, __len, false);
- __s = __cs;
- __len = __w;
- }
- __out._M_write(__s, __len);
- __out.width(0);
- }
- return __out;
- }
-
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
// NB: This syntax is a GNU extension.
Index: include/std/std_ostream.h
===================================================================
--- include/std/std_ostream.h (revision 117648)
+++ include/std/std_ostream.h (working copy)
@@ -92,6 +92,11 @@
friend basic_ostream<_CharT2, _Traits2>&
operator<<(basic_ostream<_CharT2, _Traits2>&, const char*);
+ template<typename _CharT2, typename _Traits2, typename _Alloc>
+ friend basic_ostream<_CharT2, _Traits2>&
+ operator<<(basic_ostream<_CharT2, _Traits2>&,
+ const basic_string<_CharT2, _Traits2, _Alloc>&);
+
// [27.6.2.2] constructor/destructor
/**
* @brief Base constructor.
@@ -288,11 +293,25 @@
void
_M_write(const char_type* __s, streamsize __n)
{
- streamsize __put = this->rdbuf()->sputn(__s, __n);
+ const streamsize __put = this->rdbuf()->sputn(__s, __n);
if (__put != __n)
this->setstate(ios_base::badbit);
}
+ void
+ _M_write(char_type __c, streamsize __n)
+ {
+ for (; __n > 0; --__n)
+ {
+ const int_type __put = this->rdbuf()->sputc(__c);
+ if (traits_type::eq_int_type(__put, traits_type::eof()))
+ {
+ this->setstate(ios_base::badbit);
+ break;
+ }
+ }
+ }
+
/**
* @brief Character string insertion.
* @param s The array to insert.
@@ -366,6 +385,9 @@
template<typename _ValueT>
__ostream_type&
_M_insert(_ValueT __v);
+
+ __ostream_type&
+ _M_insert(const char_type* __s, streamsize __n);
};
/**
@@ -448,7 +470,8 @@
*/
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
- operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c);
+ operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)
+ { return __out._M_insert(&__c, 1); }
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
@@ -458,7 +481,8 @@
// Specialization
template <class _Traits>
basic_ostream<char, _Traits>&
- operator<<(basic_ostream<char, _Traits>& __out, char __c);
+ operator<<(basic_ostream<char, _Traits>& __out, char __c)
+ { return __out._M_insert(&__c, 1); }
// Signed and unsigned
template<class _Traits>
@@ -488,7 +512,14 @@
*/
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
- operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s);
+ operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)
+ {
+ if (!__s)
+ __out.setstate(ios_base::badbit);
+ else
+ __out._M_insert(__s, static_cast<streamsize>(_Traits::length(__s)));
+ return __out;
+ }
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits> &
@@ -497,8 +528,15 @@
// Partial specializationss
template<class _Traits>
basic_ostream<char, _Traits>&
- operator<<(basic_ostream<char, _Traits>& __out, const char* __s);
-
+ operator<<(basic_ostream<char, _Traits>& __out, const char* __s)
+ {
+ if (!__s)
+ __out.setstate(ios_base::badbit);
+ else
+ __out._M_insert(__s, static_cast<streamsize>(_Traits::length(__s)));
+ return __out;
+ }
+
// Signed and unsigned
template<class _Traits>
basic_ostream<char, _Traits>&
Index: docs/html/ext/howto.html
===================================================================
--- docs/html/ext/howto.html (revision 117655)
+++ docs/html/ext/howto.html (working copy)
@@ -593,6 +593,12 @@
<dd>In case of input_iterator/output_iterator rely on Assignability of
input_iterator' value_type.
</dd>
+
+ <dt><a href="lwg-active.html#586">586</a>:
+ <em>string inserter not a formatted function</em>
+ </dt>
+ <dd>Change it to be a formatted output function (i.e. catch exceptions).
+ </dd>
<!--
<dt><a href="lwg-defects.html#"></a>:
<em></em>
Index: testsuite/27_io/basic_ostream/inserters_character/wchar_t/28277-2.cc
===================================================================
--- testsuite/27_io/basic_ostream/inserters_character/wchar_t/28277-2.cc (revision 0)
+++ testsuite/27_io/basic_ostream/inserters_character/wchar_t/28277-2.cc (revision 0)
@@ -0,0 +1,49 @@
+// 2006-10-12 Paolo Carlini <pcarlini@suse.de>
+
+// Copyright (C) 2006 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 27.6.2.5.4 basic_ostream character inserters
+
+#include <ostream>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// libstdc++/28277
+void test01()
+{
+ using namespace std;
+ bool test __attribute__((unused)) = true;
+
+ wostringstream oss_01;
+ const string str_01(50, 'a');
+
+ oss_01.width(5000000);
+ const streamsize width = oss_01.width();
+
+ oss_01 << str_01.c_str();
+
+ VERIFY( oss_01.good() );
+ VERIFY( oss_01.str().size() == width );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
Index: testsuite/27_io/basic_ostream/inserters_character/wchar_t/28277-3.cc
===================================================================
--- testsuite/27_io/basic_ostream/inserters_character/wchar_t/28277-3.cc (revision 0)
+++ testsuite/27_io/basic_ostream/inserters_character/wchar_t/28277-3.cc (revision 0)
@@ -0,0 +1,48 @@
+// 2006-10-12 Paolo Carlini <pcarlini@suse.de>
+
+// Copyright (C) 2006 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 27.6.2.5.4 basic_ostream character inserters
+
+#include <iostream>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// libstdc++/28277
+void test01()
+{
+ using namespace std;
+ bool test __attribute__((unused)) = true;
+
+ wostringstream oss_01;
+
+ oss_01.width(5000000);
+ const streamsize width = oss_01.width();
+
+ oss_01 << L'a';
+
+ VERIFY( oss_01.good() );
+ VERIFY( oss_01.str().size() == width );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
Index: testsuite/27_io/basic_ostream/inserters_character/wchar_t/28277-4.cc
===================================================================
--- testsuite/27_io/basic_ostream/inserters_character/wchar_t/28277-4.cc (revision 0)
+++ testsuite/27_io/basic_ostream/inserters_character/wchar_t/28277-4.cc (revision 0)
@@ -0,0 +1,49 @@
+// 2006-10-12 Paolo Carlini <pcarlini@suse.de>
+
+// Copyright (C) 2006 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 27.6.2.5.4 basic_ostream character inserters
+
+#include <ostream>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// libstdc++/28277
+void test01()
+{
+ using namespace std;
+ bool test __attribute__((unused)) = true;
+
+ wostringstream oss_01;
+ const wstring str_01(50, L'a');
+
+ oss_01.width(5000000);
+ const streamsize width = oss_01.width();
+
+ oss_01 << str_01.c_str();
+
+ VERIFY( oss_01.good() );
+ VERIFY( oss_01.str().size() == width );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
Index: testsuite/27_io/basic_ostream/inserters_character/char/28277-3.cc
===================================================================
--- testsuite/27_io/basic_ostream/inserters_character/char/28277-3.cc (revision 0)
+++ testsuite/27_io/basic_ostream/inserters_character/char/28277-3.cc (revision 0)
@@ -0,0 +1,48 @@
+// 2006-10-12 Paolo Carlini <pcarlini@suse.de>
+
+// Copyright (C) 2006 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 27.6.2.5.4 basic_ostream character inserters
+
+#include <iostream>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// libstdc++/28277
+void test01()
+{
+ using namespace std;
+ bool test __attribute__((unused)) = true;
+
+ ostringstream oss_01;
+
+ oss_01.width(20000000);
+ const streamsize width = oss_01.width();
+
+ oss_01 << 'a';
+
+ VERIFY( oss_01.good() );
+ VERIFY( oss_01.str().size() == width );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
Index: testsuite/27_io/basic_ostream/inserters_character/char/28277-4.cc
===================================================================
--- testsuite/27_io/basic_ostream/inserters_character/char/28277-4.cc (revision 0)
+++ testsuite/27_io/basic_ostream/inserters_character/char/28277-4.cc (revision 0)
@@ -0,0 +1,49 @@
+// 2006-10-12 Paolo Carlini <pcarlini@suse.de>
+
+// Copyright (C) 2006 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 27.6.2.5.4 basic_ostream character inserters
+
+#include <ostream>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// libstdc++/28277
+void test01()
+{
+ using namespace std;
+ bool test __attribute__((unused)) = true;
+
+ ostringstream oss_01;
+ const string str_01(50, 'a');
+
+ oss_01.width(20000000);
+ const streamsize width = oss_01.width();
+
+ oss_01 << str_01.c_str();
+
+ VERIFY( oss_01.good() );
+ VERIFY( oss_01.str().size() == width );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
Index: testsuite/21_strings/basic_string/inserters_extractors/wchar_t/28277.cc
===================================================================
--- testsuite/21_strings/basic_string/inserters_extractors/wchar_t/28277.cc (revision 0)
+++ testsuite/21_strings/basic_string/inserters_extractors/wchar_t/28277.cc (revision 0)
@@ -0,0 +1,49 @@
+// 2006-10-12 Paolo Carlini <pcarlini@suse.de>
+
+// Copyright (C) 2006 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 21.3.7.9 inserters and extractors
+
+#include <ostream>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// libstdc++/28277
+void test01()
+{
+ using namespace std;
+ bool test __attribute__((unused)) = true;
+
+ wostringstream oss_01;
+ const wstring str_01(50, L'a');
+
+ oss_01.width(5000000);
+ const streamsize width = oss_01.width();
+
+ oss_01 << str_01;
+
+ VERIFY( oss_01.good() );
+ VERIFY( oss_01.str().size() == width );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
Index: testsuite/21_strings/basic_string/inserters_extractors/char/28277.cc
===================================================================
--- testsuite/21_strings/basic_string/inserters_extractors/char/28277.cc (revision 0)
+++ testsuite/21_strings/basic_string/inserters_extractors/char/28277.cc (revision 0)
@@ -0,0 +1,49 @@
+// 2006-10-12 Paolo Carlini <pcarlini@suse.de>
+
+// Copyright (C) 2006 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// 21.3.7.9 inserters and extractors
+
+#include <ostream>
+#include <sstream>
+#include <testsuite_hooks.h>
+
+// libstdc++/28277
+void test01()
+{
+ using namespace std;
+ bool test __attribute__((unused)) = true;
+
+ ostringstream oss_01;
+ const string str_01(50, 'a');
+
+ oss_01.width(20000000);
+ const streamsize width = oss_01.width();
+
+ oss_01 << str_01;
+
+ VERIFY( oss_01.good() );
+ VERIFY( oss_01.str().size() == width );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
Index: config/abi/pre/gnu.ver
===================================================================
--- config/abi/pre/gnu.ver (revision 117648)
+++ config/abi/pre/gnu.ver (working copy)
@@ -285,7 +285,7 @@
_ZNSoC*;
_ZNSoD*;
_ZNKSo6sentrycvbEv;
- _ZNSo8_M_write*;
+ _ZNSo8_M_writeEPKc[il];
_ZNSo[0-9][a-z]*;
_ZNSolsE*[^g];
@@ -299,7 +299,7 @@
_ZNSt13basic_ostreamIwSt11char_traitsIwEE5tellpEv;
_ZNSt13basic_ostreamIwSt11char_traitsIwEE5writeEPKw*;
_ZNSt13basic_ostreamIwSt11char_traitsIwEE6sentry*;
- _ZNSt13basic_ostreamIwSt11char_traitsIwEE8_M_write*;
+ _ZNSt13basic_ostreamIwSt11char_traitsIwEE8_M_writeEPKw[il];
_ZNSt13basic_ostreamIwSt11char_traitsIwEElsE*[^g];
# std::ostream operators and inserters
@@ -659,6 +659,9 @@
_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractI[^g]*;
_ZSt21__copy_streambufs_eofI[cw]St11char_traitsI[cw]EE[il]PSt15basic_streambuf*;
+
+ _ZNSo9_M_insertEPKc[il];
+ _ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertEPKw[il];
} GLIBCXX_3.4.8;