diff options
author | Benjamin Kosnik <bkoz@redhat.com> | 2003-11-27 08:14:25 +0000 |
---|---|---|
committer | Benjamin Kosnik <bkoz@gcc.gnu.org> | 2003-11-27 08:14:25 +0000 |
commit | 12841eb3d032e926775f49834b8941f57a047baf (patch) | |
tree | 27f6d0d3d427d9db5da892e2b7f7f741d945f41a /libstdc++-v3/include/bits/ostream.tcc | |
parent | b483cfb7a714d1d4ca0868241f69b31d44c51e55 (diff) | |
download | gcc-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.tcc | 310 |
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) |