Index: include/bits/ostream.tcc =================================================================== RCS file: /home/petur/cvsroot/gcc/libstdc++-v3/include/bits/ostream.tcc,v retrieving revision 1.1.1.7 diff -c -3 -p -r1.1.1.7 ostream.tcc *** include/bits/ostream.tcc 26 Aug 2003 16:13:08 -0000 1.1.1.7 --- include/bits/ostream.tcc 22 Sep 2003 21:12:20 -0000 *************** namespace std *** 64,84 **** basic_ostream<_CharT, _Traits>:: operator<<(__ostream_type& (*__pf)(__ostream_type&)) { ! sentry __cerb(*this); ! if (__cerb) ! { ! try ! { __pf(*this); } ! 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; ! } ! } ! return *this; } template --- 64,73 ---- basic_ostream<_CharT, _Traits>:: operator<<(__ostream_type& (*__pf)(__ostream_type&)) { ! // _GLIBCXX_RESOLVE_LIB_DEFECTS ! // DR 60. What is a formatted input function? ! // The inserters for manipulators are *not* formatted output functions. ! return __pf(*this); } template *************** namespace std *** 86,105 **** basic_ostream<_CharT, _Traits>:: operator<<(__ios_type& (*__pf)(__ios_type&)) { ! sentry __cerb(*this); ! if (__cerb) ! { ! try ! { __pf(*this); } ! 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; ! } ! } return *this; } --- 75,84 ---- basic_ostream<_CharT, _Traits>:: operator<<(__ios_type& (*__pf)(__ios_type&)) { ! // _GLIBCXX_RESOLVE_LIB_DEFECTS ! // DR 60. What is a formatted input function? ! // The inserters for manipulators are *not* formatted output functions. ! __pf(*this); return *this; } *************** namespace std *** 108,127 **** basic_ostream<_CharT, _Traits>:: operator<<(ios_base& (*__pf)(ios_base&)) { ! sentry __cerb(*this); ! if (__cerb) ! { ! try ! { __pf(*this); } ! 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; ! } ! } return *this; } --- 87,96 ---- basic_ostream<_CharT, _Traits>:: operator<<(ios_base& (*__pf)(ios_base&)) { ! // _GLIBCXX_RESOLVE_LIB_DEFECTS ! // DR 60. What is a formatted input function? ! // The inserters for manipulators are *not* formatted output functions. ! __pf(*this); return *this; } *************** namespace std *** 378,389 **** basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::put(char_type __c) { sentry __cerb(*this); if (__cerb) { ! int_type __put = this->rdbuf()->sputc(__c); ! if (traits_type::eq_int_type(__put, traits_type::eof())) ! this->setstate(ios_base::badbit); } return *this; } --- 347,373 ---- basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::put(char_type __c) { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // basic_ostream::put(char_type) is an unformatted output function. + // DR 63. Exception-handling policy for unformatted output. + // Unformatted output functions should catch exceptions thrown + // from streambuf members. sentry __cerb(*this); if (__cerb) { ! try ! { ! int_type __put = this->rdbuf()->sputc(__c); ! if (traits_type::eq_int_type(__put, traits_type::eof())) ! this->setstate(ios_base::badbit); ! } ! catch (...) ! { ! this->_M_setstate(ios_base::badbit); ! if ((this->exceptions() & ios_base::badbit) != 0) ! __throw_exception_again; ! } } return *this; } *************** namespace std *** 392,400 **** basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::write(const _CharT* __s, streamsize __n) { sentry __cerb(*this); if (__cerb) ! _M_write(__s, __n); return *this; } --- 376,400 ---- basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::write(const _CharT* __s, streamsize __n) { + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // basic_ostream::write(const char_type*, streamsize) is an + // unformatted output function. + // DR 63. Exception-handling policy for unformatted output. + // Unformatted output functions should catch exceptions thrown + // from streambuf members. sentry __cerb(*this); if (__cerb) ! { ! try ! { _M_write(__s, __n); } ! catch (...) ! { ! this->_M_setstate(ios_base::badbit); ! if ((this->exceptions() & ios_base::badbit) != 0) ! __throw_exception_again; ! } ! } return *this; } *************** namespace std *** 402,413 **** basic_ostream<_CharT, _Traits>& basic_ostream<_CharT, _Traits>::flush() { ! sentry __cerb(*this); ! if (__cerb) ! { ! if (this->rdbuf() && this->rdbuf()->pubsync() == -1) ! this->setstate(ios_base::badbit); ! } return *this; } --- 402,412 ---- basic_ostream<_CharT, _Traits>& 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); return *this; } Index: testsuite/testsuite_io.h =================================================================== RCS file: /home/petur/cvsroot/gcc/libstdc++-v3/testsuite/testsuite_io.h,v retrieving revision 1.1.1.3 diff -c -3 -p -r1.1.1.3 testsuite_io.h *** testsuite/testsuite_io.h 31 Jul 2003 20:56:25 -0000 1.1.1.3 --- testsuite/testsuite_io.h 22 Sep 2003 21:19:06 -0000 *************** namespace __gnu_test *** 73,78 **** --- 73,102 ---- } }; + + // Used to check if basic_streambuf::pubsync() has been called. + // This is useful for checking if a function creates [io]stream::sentry + // objects, since the sentry constructors call tie()->flush(). + class sync_streambuf : public std::streambuf + { + private: + bool m_sync_called; + + public: + sync_streambuf() + : m_sync_called(false) + { } + + bool sync_called() const + { return m_sync_called; } + + protected: + int sync() + { + m_sync_called = true; + return 0; + } + }; }; // namespace __gnu_test #endif // _GLIBCXX_TESTSUITE_IO_H Index: testsuite/27_io/basic_ostream/flush/char/2.cc =================================================================== RCS file: testsuite/27_io/basic_ostream/flush/char/2.cc diff -N testsuite/27_io/basic_ostream/flush/char/2.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/27_io/basic_ostream/flush/char/2.cc 22 Sep 2003 21:02:37 -0000 *************** *** 0 **** --- 1,66 ---- + // 2003-09-22 Petur Runolfsson + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // 27.6.2.6 Unformatted output functions + // + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // basic_ostream::flush() does not behave as an unformatted output function. + + #include + #include + #include + + void test02() + { + bool test = true; + + __gnu_test::sync_streambuf buf; + std::ostream os(&buf); + + __gnu_test::sync_streambuf buf_tie; + std::ostream os_tie(&buf_tie); + + // No sentry should be constructed so os.tie()->flush() should not be + // called. + os.tie(&os_tie); + + os.flush(); + + VERIFY( os.good() ); + VERIFY( buf.sync_called() ); + VERIFY( !buf_tie.sync_called() ); + + // os.rdbuf()->pubsync() should be called even if !os.good(). + os.setstate(std::ios_base::eofbit); + + os.flush(); + + VERIFY( os.rdstate() == std::ios_base::eofbit ); + VERIFY( buf.sync_called() ); + VERIFY( !buf_tie.sync_called() ); + } + + int main() + { + test02(); + return 0; + } + Index: testsuite/27_io/basic_ostream/inserters_other/char/5.cc =================================================================== RCS file: testsuite/27_io/basic_ostream/inserters_other/char/5.cc diff -N testsuite/27_io/basic_ostream/inserters_other/char/5.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/27_io/basic_ostream/inserters_other/char/5.cc 22 Sep 2003 20:42:03 -0000 *************** *** 0 **** --- 1,99 ---- + // 2003-09-22 Petur Runolfsson + + // Copyright (C) 2003 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // 27.6.2.5.3 basic_ostream manipulator inserters + // + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // Inserters for manipulators do not behave as formatted output functions. + + #include + #include + #include + #include + + std::ostream& func1(std::ostream&) + { throw std::runtime_error(""); } + + std::ios& func2(std::ios&) + { throw std::runtime_error(""); } + + std::ios_base& func3(std::ios_base&) + { throw std::runtime_error(""); } + + template + void test(T& (*f)(T&)) + { + bool test = true; + + __gnu_test::sync_streambuf buf; + std::ostream os(&buf); + + __gnu_test::sync_streambuf buf_tie; + std::ostream os_tie(&buf_tie); + + // No sentry should be constructed so os.tie()->flush() should not be + // called. + os.tie(&os_tie); + + try + { + os << f; + // Exceptions thrown by f should not be caught + VERIFY( false ); + } + catch (std::runtime_error&) + { + } + + // Exceptions thrown by f should not cause badbit to be set + VERIFY( os.good() ); + VERIFY( !buf_tie.sync_called() ); + + // The manipulator should be called even if !os.good(). + os.setstate(std::ios_base::eofbit); + + try + { + os << f; + // Exceptions thrown by f should not be caught + VERIFY( false ); + } + catch (std::runtime_error&) + { + } + + // Exceptions thrown by f should not cause badbit to be set + VERIFY( os.rdstate() == std::ios_base::eofbit ); + VERIFY( !buf_tie.sync_called() ); + } + + void test05() + { + test(&func1); + test(&func2); + test(&func3); + } + + int main() + { + test05(); + return 0; + } Index: testsuite/27_io/basic_ostream/put/char/1.cc =================================================================== RCS file: testsuite/27_io/basic_ostream/put/char/1.cc diff -N testsuite/27_io/basic_ostream/put/char/1.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/27_io/basic_ostream/put/char/1.cc 22 Sep 2003 20:57:47 -0000 *************** *** 0 **** --- 1,72 ---- + // 2003-09-22 Petur Runolfsson + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // 27.6.2.6 Unformatted output functions + // + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // basic_ostream::put(char_type) is an unformatted output function. + // DR 63. Exception-handling policy for unformatted output. + // Unformatted output functions should catch exceptions thrown + // from streambuf members. + + #include + #include + #include + + class Buf : public std::streambuf + { + protected: + virtual int_type overflow(int_type = traits_type::eof()) + { throw 0; } + }; + + void test01() + { + bool test = true; + + Buf buf; + std::ostream os(&buf); + + VERIFY( os.good() ); + + os.put('a'); + + VERIFY( os.rdstate() == std::ios_base::badbit ); + + os.clear(); + os.exceptions(std::ios_base::badbit); + + try + { + os.put('b'); + VERIFY( false ); + } + catch (int) + { + VERIFY( os.rdstate() == std::ios_base::badbit ); + } + } + + int main() + { + test01(); + return 0; + } Index: testsuite/27_io/basic_ostream/write/char/1.cc =================================================================== RCS file: testsuite/27_io/basic_ostream/write/char/1.cc diff -N testsuite/27_io/basic_ostream/write/char/1.cc *** /dev/null 1 Jan 1970 00:00:00 -0000 --- testsuite/27_io/basic_ostream/write/char/1.cc 22 Sep 2003 20:59:11 -0000 *************** *** 0 **** --- 1,73 ---- + // 2003-09-22 Petur Runolfsson + + // Copyright (C) 2003 Free Software Foundation, Inc. + // + // 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, + // USA. + + // 27.6.2.6 Unformatted output functions + // + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 60. What is a formatted input function? + // basic_ostream::write(const char_type*, streamsize) is an unformatted + // output function. + // DR 63. Exception-handling policy for unformatted output. + // Unformatted output functions should catch exceptions thrown + // from streambuf members. + + #include + #include + #include + + class Buf : public std::streambuf + { + protected: + virtual int_type overflow(int_type = traits_type::eof()) + { throw 0; } + }; + + void test01() + { + bool test = true; + + Buf buf; + std::ostream os(&buf); + + VERIFY( os.good() ); + + os.write("a", 1); + + VERIFY( os.rdstate() == std::ios_base::badbit ); + + os.clear(); + os.exceptions(std::ios_base::badbit); + + try + { + os.write("b", 1); + VERIFY( false ); + } + catch (int) + { + VERIFY( os.rdstate() == std::ios_base::badbit ); + } + } + + int main() + { + test01(); + return 0; + }