re PR libstdc++/12594 (DRs 60 [TC] and 63 [TC] not implemented)

2003-11-13  Petur Runolfsson  <peturr02@ru.is>

	PR libstdc++/12594
	* include/bits/ostream.tcc
	(basic_ostream::operator<<(basic_ostream& (*)(basic_ostream&)),
	basic_ostream::operator<<(basic_ios& (*)(basic_ios&)),
	basic_ostream::operator<<(ios_base& (*)(ios_base&))):
	Implement the resolution of DR 60 (TC): These are not formatted
	output functions so don't construct sentry objects and don't
	catch exceptions.
	(basic_ostream::put, basic_ostream::write): Implement the
	resolution of DR 63 (TC) by catching exceptions and setting
	badbit.
	(basic_ostream::flush): Implement the resolution of DR 60 (TC):
	This is not an unformatted output function so don't construct
	a sentry object.
	* testsuite/testsuite_io.h (sync_streambuf): Define.
	* testsuite/27_io/basic_ostream/flush/char/2.cc: New test.
	* testsuite/27_io/basic_ostream/inserters_other/char/5.cc: New test.
	* testsuite/27_io/basic_ostream/put/char/1.cc: New test.
	* testsuite/27_io/basic_ostream/write/char/1.cc: New test.

From-SVN: r73551
This commit is contained in:
Petur Runolfsson 2003-11-13 17:43:48 +00:00 committed by Benjamin Kosnik
parent 148a82c8ad
commit 5681c890b6
7 changed files with 408 additions and 53 deletions

View File

@ -1,3 +1,25 @@
2003-11-13 Petur Runolfsson <peturr02@ru.is>
PR libstdc++/12594
* include/bits/ostream.tcc
(basic_ostream::operator<<(basic_ostream& (*)(basic_ostream&)),
basic_ostream::operator<<(basic_ios& (*)(basic_ios&)),
basic_ostream::operator<<(ios_base& (*)(ios_base&))):
Implement the resolution of DR 60 (TC): These are not formatted
output functions so don't construct sentry objects and don't
catch exceptions.
(basic_ostream::put, basic_ostream::write): Implement the
resolution of DR 63 (TC) by catching exceptions and setting
badbit.
(basic_ostream::flush): Implement the resolution of DR 60 (TC):
This is not an unformatted output function so don't construct
a sentry object.
* testsuite/testsuite_io.h (sync_streambuf): Define.
* testsuite/27_io/basic_ostream/flush/char/2.cc: New test.
* testsuite/27_io/basic_ostream/inserters_other/char/5.cc: New test.
* testsuite/27_io/basic_ostream/put/char/1.cc: New test.
* testsuite/27_io/basic_ostream/write/char/1.cc: New test.
2003-11-13 Paolo Carlini <pcarlini@suse.de>
* testsuite/27_io/basic_filebuf/overflow/wchar_t/11305-1:

View File

@ -64,21 +64,10 @@ namespace std
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;
// _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<typename _CharT, typename _Traits>
@ -86,20 +75,10 @@ namespace std
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;
}
}
// _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;
}
@ -108,20 +87,10 @@ namespace std
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;
}
}
// _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;
}
@ -378,12 +347,27 @@ namespace std
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)
{
int_type __put = this->rdbuf()->sputc(__c);
if (traits_type::eq_int_type(__put, traits_type::eof()))
this->setstate(ios_base::badbit);
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;
}
@ -392,9 +376,25 @@ namespace std
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)
_M_write(__s, __n);
{
try
{ _M_write(__s, __n); }
catch (...)
{
this->_M_setstate(ios_base::badbit);
if ((this->exceptions() & ios_base::badbit) != 0)
__throw_exception_again;
}
}
return *this;
}
@ -402,12 +402,11 @@ namespace std
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);
}
// _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;
}

View File

@ -0,0 +1,66 @@
// 2003-09-22 Petur Runolfsson <peturr02@ru.is>
// 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 <ostream>
#include <testsuite_hooks.h>
#include <testsuite_io.h>
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;
}

View File

@ -0,0 +1,99 @@
// 2003-09-22 Petur Runolfsson <peturr02@ru.is>
// 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 <ostream>
#include <stdexcept>
#include <testsuite_hooks.h>
#include <testsuite_io.h>
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<typename T>
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;
}

View File

@ -0,0 +1,72 @@
// 2003-09-22 Petur Runolfsson <peturr02@ru.is>
// 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 <ostream>
#include <streambuf>
#include <testsuite_hooks.h>
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;
}

View File

@ -0,0 +1,73 @@
// 2003-09-22 Petur Runolfsson <peturr02@ru.is>
// 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 <ostream>
#include <streambuf>
#include <testsuite_hooks.h>
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;
}

View File

@ -73,6 +73,30 @@ namespace __gnu_test
}
};
// 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