aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/bits/ostream.tcc
diff options
context:
space:
mode:
authorBenjamin Kosnik <bkoz@redhat.com>2003-11-27 08:14:25 +0000
committerBenjamin Kosnik <bkoz@gcc.gnu.org>2003-11-27 08:14:25 +0000
commit12841eb3d032e926775f49834b8941f57a047baf (patch)
tree27f6d0d3d427d9db5da892e2b7f7f741d945f41a /libstdc++-v3/include/bits/ostream.tcc
parentb483cfb7a714d1d4ca0868241f69b31d44c51e55 (diff)
downloadgcc-12841eb3d032e926775f49834b8941f57a047baf.zip
gcc-12841eb3d032e926775f49834b8941f57a047baf.tar.gz
gcc-12841eb3d032e926775f49834b8941f57a047baf.tar.bz2
re PR libstdc++/9371 (Bad exception handling in i/ostream::operator>>/<<(streambuf*))
2003-11-26 Benjamin Kosnik <bkoz@redhat.com> PR libstdc++/9371 PR libstdc++/9546 PR libstdc++/10093 PR libstdc++/10095 * include/bits/basic_ios.h (basic_ios::setstate): Elide if goodbit. (basic_ios::_M_setstate): Consolidate common error handling code. * include/bits/basic_ios.tcc: Tweak. * include/bits/fstream.tcc: Tweak. * include/bits/istream.tcc: Use _M_setstate for common exception handling. Move setstate calls after catch. (basic_istream::tellg): Check for exceptions thrown by streambuf virtual functions. (basic_istream::seekg): Same. * include/bits/ostream.tcc: Same, but for ostream. (basic_ostream::flush): Check for exceptions thrown by streambuf virtual functions. (basic_istream::tellp): Same. (basic_istream::seekp): Same. * include/bits/locale_facets.tcc: Tweak. * include/bits/streambuf.tcc: Tweak. (__copy_streambufs): Propagate exceptions. * testsuite/testsuite_io.h (fail_streambuf): New. (fail_num_get): New. (fail_num_put): New. (facet_error): New. (underflow_error): New. (overflow_error): New. (positioning_error): New. * testsuite/27_io/basic_istream/exceptions/char/9561.cc: Tweak. * testsuite/27_io/basic_istream/extractors_arithmetic/char/ exceptions_badbit_throw.cc, exceptions_failbit.cc, exceptions_failbit_throw.cc: New. * testsuite/27_io/basic_istream/extractors_other/char/ error_failbit.cc, exceptions_badbit_throw.cc, exceptions_failbit_throw.cc, exceptions_null.cc: New. * testsuite/27_io/basic_istream/seekg/char/exceptions_badbit_throw.cc: New. * testsuite/27_io/basic_istream/tellg/char/exceptions_badbit_throw.cc: New. * testsuite/27_io/basic_ostream/flush/char/exceptions_badbit_throw.cc: New. * testsuite/27_io/basic_ostream/inserters_arithmetic/char/ exceptions_badbit_throw.cc, exceptions_failbit_throw.cc: New. * testsuite/27_io/basic_ostream/inserters_other/char/ error_failbit.cc, exceptions_badbit_throw.cc, exceptions_failbit_throw.cc, exceptions_null.cc: New. * testsuite/27_io/basic_ostream/seekp/char/exceptions_badbit_throw.cc: New. * testsuite/27_io/basic_ostream/tellp/char/exceptions_badbit_throw.cc: New. From-SVN: r73979
Diffstat (limited to 'libstdc++-v3/include/bits/ostream.tcc')
-rw-r--r--libstdc++-v3/include/bits/ostream.tcc310
1 files changed, 139 insertions, 171 deletions
diff --git a/libstdc++-v3/include/bits/ostream.tcc b/libstdc++-v3/include/bits/ostream.tcc
index 3235754..fecaa93 100644
--- a/libstdc++-v3/include/bits/ostream.tcc
+++ b/libstdc++-v3/include/bits/ostream.tcc
@@ -43,7 +43,7 @@ namespace std
{
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>::sentry::
- sentry(basic_ostream<_CharT,_Traits>& __os)
+ sentry(basic_ostream<_CharT, _Traits>& __os)
: _M_os(__os)
{
// XXX MT
@@ -96,62 +96,35 @@ namespace std
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
- basic_ostream<_CharT, _Traits>::operator<<(__streambuf_type* __sbin)
- {
- sentry __cerb(*this);
- if (__cerb && __sbin)
- {
- try
- {
- if (!__copy_streambufs(*this, __sbin, this->rdbuf()))
- this->setstate(ios_base::failbit);
- }
- catch(...)
- {
- // 27.6.2.5.1 Common requirements.
- // Turn this on without causing an ios::failure to be thrown.
- this->_M_setstate(ios_base::badbit);
- if ((this->exceptions() & ios_base::badbit) != 0)
- __throw_exception_again;
- }
- }
- else if (!__sbin)
- this->setstate(ios_base::badbit);
- return *this;
- }
-
- template<typename _CharT, typename _Traits>
- basic_ostream<_CharT, _Traits>&
- basic_ostream<_CharT, _Traits>::operator<<(bool __n)
+ basic_ostream<_CharT, _Traits>::
+ operator<<(bool __n)
{
sentry __cerb(*this);
if (__cerb)
{
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
try
{
const __num_put_type& __np = __check_facet(this->_M_num_put);
if (__np.put(*this, *this, this->fill(), __n).failed())
- this->setstate(ios_base::badbit);
+ __err |= ios_base::badbit;
}
catch(...)
- {
- // 27.6.1.2.1 Common requirements.
- // Turn this on without causing an ios::failure to be thrown.
- this->_M_setstate(ios_base::badbit);
- if ((this->exceptions() & ios_base::badbit) != 0)
- __throw_exception_again;
- }
+ { this->_M_setstate(ios_base::badbit); }
+ this->setstate(__err);
}
return *this;
}
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
- basic_ostream<_CharT, _Traits>::operator<<(long __n)
+ basic_ostream<_CharT, _Traits>::
+ operator<<(long __n)
{
sentry __cerb(*this);
if (__cerb)
{
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
try
{
bool __b = false;
@@ -166,41 +139,33 @@ namespace std
else
__b = __np.put(*this, *this, __c, __n).failed();
if (__b)
- this->setstate(ios_base::badbit);
+ __err |= ios_base::badbit;
}
catch(...)
- {
- // 27.6.1.2.1 Common requirements.
- // Turn this on without causing an ios::failure to be thrown.
- this->_M_setstate(ios_base::badbit);
- if ((this->exceptions() & ios_base::badbit) != 0)
- __throw_exception_again;
- }
+ { this->_M_setstate(ios_base::badbit); }
+ this->setstate(__err);
}
return *this;
}
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
- basic_ostream<_CharT, _Traits>::operator<<(unsigned long __n)
+ basic_ostream<_CharT, _Traits>::
+ operator<<(unsigned long __n)
{
sentry __cerb(*this);
if (__cerb)
{
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
try
{
const __num_put_type& __np = __check_facet(this->_M_num_put);
if (__np.put(*this, *this, this->fill(), __n).failed())
- this->setstate(ios_base::badbit);
+ __err |= ios_base::badbit;
}
catch(...)
- {
- // 27.6.1.2.1 Common requirements.
- // Turn this on without causing an ios::failure to be thrown.
- this->_M_setstate(ios_base::badbit);
- if ((this->exceptions() & ios_base::badbit) != 0)
- __throw_exception_again;
- }
+ { this->_M_setstate(ios_base::badbit); }
+ this->setstate(__err);
}
return *this;
}
@@ -208,11 +173,13 @@ namespace std
#ifdef _GLIBCXX_USE_LONG_LONG
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
- basic_ostream<_CharT, _Traits>::operator<<(long long __n)
+ basic_ostream<_CharT, _Traits>::
+ operator<<(long long __n)
{
sentry __cerb(*this);
if (__cerb)
{
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
try
{
bool __b = false;
@@ -228,41 +195,33 @@ namespace std
else
__b = __np.put(*this, *this, __c, __n).failed();
if (__b)
- this->setstate(ios_base::badbit);
+ __err |= ios_base::badbit;
}
catch(...)
- {
- // 27.6.1.2.1 Common requirements.
- // Turn this on without causing an ios::failure to be thrown.
- this->_M_setstate(ios_base::badbit);
- if ((this->exceptions() & ios_base::badbit) != 0)
- __throw_exception_again;
- }
+ { this->_M_setstate(ios_base::badbit); }
+ this->setstate(__err);
}
return *this;
}
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
- basic_ostream<_CharT, _Traits>::operator<<(unsigned long long __n)
+ basic_ostream<_CharT, _Traits>::
+ operator<<(unsigned long long __n)
{
sentry __cerb(*this);
if (__cerb)
{
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
try
{
const __num_put_type& __np = __check_facet(this->_M_num_put);
if (__np.put(*this, *this, this->fill(), __n).failed())
- this->setstate(ios_base::badbit);
+ __err |= ios_base::badbit;
}
catch(...)
- {
- // 27.6.1.2.1 Common requirements.
- // Turn this on without causing an ios::failure to be thrown.
- this->_M_setstate(ios_base::badbit);
- if ((this->exceptions() & ios_base::badbit) != 0)
- __throw_exception_again;
- }
+ { this->_M_setstate(ios_base::badbit); }
+ this->setstate(__err);
}
return *this;
}
@@ -270,82 +229,97 @@ namespace std
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
- basic_ostream<_CharT, _Traits>::operator<<(double __n)
+ basic_ostream<_CharT, _Traits>::
+ operator<<(double __n)
{
sentry __cerb(*this);
if (__cerb)
{
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
try
{
const __num_put_type& __np = __check_facet(this->_M_num_put);
if (__np.put(*this, *this, this->fill(), __n).failed())
- this->setstate(ios_base::badbit);
+ __err |= ios_base::badbit;
}
catch(...)
- {
- // 27.6.1.2.1 Common requirements.
- // Turn this on without causing an ios::failure to be thrown.
- this->_M_setstate(ios_base::badbit);
- if ((this->exceptions() & ios_base::badbit) != 0)
- __throw_exception_again;
- }
+ { this->_M_setstate(ios_base::badbit); }
+ this->setstate(__err);
}
return *this;
}
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
- basic_ostream<_CharT, _Traits>::operator<<(long double __n)
+ basic_ostream<_CharT, _Traits>::
+ operator<<(long double __n)
{
sentry __cerb(*this);
if (__cerb)
{
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
try
{
const __num_put_type& __np = __check_facet(this->_M_num_put);
if (__np.put(*this, *this, this->fill(), __n).failed())
- this->setstate(ios_base::badbit);
+ __err |= ios_base::badbit;
}
catch(...)
- {
- // 27.6.1.2.1 Common requirements.
- // Turn this on without causing an ios::failure to be thrown.
- this->_M_setstate(ios_base::badbit);
- if ((this->exceptions() & ios_base::badbit) != 0)
- __throw_exception_again;
- }
+ { this->_M_setstate(ios_base::badbit); }
+ this->setstate(__err);
}
return *this;
}
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
- basic_ostream<_CharT, _Traits>::operator<<(const void* __n)
+ basic_ostream<_CharT, _Traits>::
+ operator<<(const void* __n)
{
sentry __cerb(*this);
if (__cerb)
{
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
try
{
const __num_put_type& __np = __check_facet(this->_M_num_put);
if (__np.put(*this, *this, this->fill(), __n).failed())
- this->setstate(ios_base::badbit);
+ __err |= ios_base::badbit;
}
catch(...)
+ { this->_M_setstate(ios_base::badbit); }
+ this->setstate(__err);
+ }
+ return *this;
+ }
+
+ template<typename _CharT, typename _Traits>
+ basic_ostream<_CharT, _Traits>&
+ basic_ostream<_CharT, _Traits>::
+ operator<<(__streambuf_type* __sbin)
+ {
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ sentry __cerb(*this);
+ if (__cerb && __sbin)
+ {
+ try
{
- // 27.6.1.2.1 Common requirements.
- // Turn this on without causing an ios::failure to be thrown.
- this->_M_setstate(ios_base::badbit);
- if ((this->exceptions() & ios_base::badbit) != 0)
- __throw_exception_again;
+ if (!__copy_streambufs(*this, __sbin, this->rdbuf()))
+ __err |= ios_base::failbit;
}
+ catch(...)
+ { this->_M_setstate(ios_base::failbit); }
}
+ else if (!__sbin)
+ __err |= ios_base::badbit;
+ this->setstate(__err);
return *this;
}
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
- basic_ostream<_CharT, _Traits>::put(char_type __c)
+ basic_ostream<_CharT, _Traits>::
+ put(char_type __c)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 60. What is a formatted input function?
@@ -356,25 +330,24 @@ namespace std
sentry __cerb(*this);
if (__cerb)
{
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
try
{
int_type __put = this->rdbuf()->sputc(__c);
if (traits_type::eq_int_type(__put, traits_type::eof()))
- this->setstate(ios_base::badbit);
+ __err |= ios_base::badbit;
}
catch (...)
- {
- this->_M_setstate(ios_base::badbit);
- if ((this->exceptions() & ios_base::badbit) != 0)
- __throw_exception_again;
- }
+ { this->_M_setstate(ios_base::badbit); }
+ this->setstate(__err);
}
return *this;
}
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
- basic_ostream<_CharT, _Traits>::write(const _CharT* __s, streamsize __n)
+ basic_ostream<_CharT, _Traits>::
+ write(const _CharT* __s, streamsize __n)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 60. What is a formatted input function?
@@ -389,71 +362,95 @@ namespace std
try
{ _M_write(__s, __n); }
catch (...)
- {
- this->_M_setstate(ios_base::badbit);
- if ((this->exceptions() & ios_base::badbit) != 0)
- __throw_exception_again;
- }
+ { this->_M_setstate(ios_base::badbit); }
}
return *this;
}
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
- basic_ostream<_CharT, _Traits>::flush()
+ basic_ostream<_CharT, _Traits>::
+ flush()
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 60. What is a formatted input function?
// basic_ostream::flush() is *not* an unformatted output function.
- if (this->rdbuf() && this->rdbuf()->pubsync() == -1)
- this->setstate(ios_base::badbit);
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ try
+ {
+ if (this->rdbuf() && this->rdbuf()->pubsync() == -1)
+ __err |= ios_base::badbit;
+ }
+ catch(...)
+ { this->_M_setstate(ios_base::badbit); }
+ this->setstate(__err);
return *this;
}
template<typename _CharT, typename _Traits>
typename basic_ostream<_CharT, _Traits>::pos_type
- basic_ostream<_CharT, _Traits>::tellp()
+ basic_ostream<_CharT, _Traits>::
+ tellp()
{
pos_type __ret = pos_type(-1);
- if (!this->fail())
- __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
+ try
+ {
+ if (!this->fail())
+ __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
+ }
+ catch(...)
+ { this->_M_setstate(ios_base::badbit); }
return __ret;
}
-
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
- basic_ostream<_CharT, _Traits>::seekp(pos_type __pos)
+ basic_ostream<_CharT, _Traits>::
+ seekp(pos_type __pos)
{
- if (!this->fail())
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ try
{
- // _GLIBCXX_RESOLVE_LIB_DEFECTS
- // 136. seekp, seekg setting wrong streams?
- pos_type __err = this->rdbuf()->pubseekpos(__pos, ios_base::out);
-
- // 129. Need error indication from seekp() and seekg()
- if (__err == pos_type(off_type(-1)))
- this->setstate(ios_base::failbit);
+ if (!this->fail())
+ {
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 136. seekp, seekg setting wrong streams?
+ pos_type __p = this->rdbuf()->pubseekpos(__pos, ios_base::out);
+
+ // 129. Need error indication from seekp() and seekg()
+ if (__p == pos_type(off_type(-1)))
+ __err |= ios_base::failbit;
+ }
}
+ catch(...)
+ { this->_M_setstate(ios_base::badbit); }
+ this->setstate(__err);
return *this;
}
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
basic_ostream<_CharT, _Traits>::
- seekp(off_type __off, ios_base::seekdir __d)
+ seekp(off_type __off, ios_base::seekdir __dir)
{
- if (!this->fail())
+ ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
+ try
{
- // _GLIBCXX_RESOLVE_LIB_DEFECTS
- // 136. seekp, seekg setting wrong streams?
- pos_type __err = this->rdbuf()->pubseekoff(__off, __d,
- ios_base::out);
-
- // 129. Need error indication from seekp() and seekg()
- if (__err == pos_type(off_type(-1)))
- this->setstate(ios_base::failbit);
+ if (!this->fail())
+ {
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 136. seekp, seekg setting wrong streams?
+ pos_type __p = this->rdbuf()->pubseekoff(__off, __dir,
+ ios_base::out);
+
+ // 129. Need error indication from seekp() and seekg()
+ if (__p == pos_type(off_type(-1)))
+ __err |= ios_base::failbit;
+ }
}
+ catch(...)
+ { this->_M_setstate(ios_base::badbit); }
+ this->setstate(__err);
return *this;
}
@@ -483,13 +480,7 @@ namespace std
__out.width(0);
}
catch(...)
- {
- // 27.6.1.2.1 Common requirements.
- // Turn this on without causing an ios::failure to be thrown.
- __out._M_setstate(ios_base::badbit);
- if ((__out.exceptions() & ios_base::badbit) != 0)
- __throw_exception_again;
- }
+ { __out._M_setstate(ios_base::badbit); }
}
return __out;
}
@@ -519,13 +510,7 @@ namespace std
__out.width(0);
}
catch(...)
- {
- // 27.6.1.2.1 Common requirements.
- // Turn this on without causing an ios::failure to be thrown.
- __out._M_setstate(ios_base::badbit);
- if ((__out.exceptions() & ios_base::badbit) != 0)
- __throw_exception_again;
- }
+ { __out._M_setstate(ios_base::badbit); }
}
return __out;
}
@@ -555,13 +540,7 @@ namespace std
__out.width(0);
}
catch(...)
- {
- // 27.6.1.2.1 Common requirements.
- // Turn this on without causing an ios::failure to be thrown.
- __out._M_setstate(ios_base::badbit);
- if ((__out.exceptions() & ios_base::badbit) != 0)
- __throw_exception_again;
- }
+ { __out._M_setstate(ios_base::badbit); }
}
else if (!__s)
__out.setstate(ios_base::badbit);
@@ -604,13 +583,7 @@ namespace std
__out.width(0);
}
catch(...)
- {
- // 27.6.1.2.1 Common requirements.
- // Turn this on without causing an ios::failure to be thrown.
- __out._M_setstate(ios_base::badbit);
- if ((__out.exceptions() & ios_base::badbit) != 0)
- __throw_exception_again;
- }
+ { __out._M_setstate(ios_base::badbit); }
}
else if (!__s)
__out.setstate(ios_base::badbit);
@@ -642,13 +615,7 @@ namespace std
__out.width(0);
}
catch(...)
- {
- // 27.6.1.2.1 Common requirements.
- // Turn this on without causing an ios::failure to be thrown.
- __out._M_setstate(ios_base::badbit);
- if ((__out.exceptions() & ios_base::badbit) != 0)
- __throw_exception_again;
- }
+ { __out._M_setstate(ios_base::badbit); }
}
else if (!__s)
__out.setstate(ios_base::badbit);
@@ -668,6 +635,7 @@ namespace std
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)