mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-02 16:23:56 +08:00
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:
parent
148a82c8ad
commit
5681c890b6
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
66
libstdc++-v3/testsuite/27_io/basic_ostream/flush/char/2.cc
Normal file
66
libstdc++-v3/testsuite/27_io/basic_ostream/flush/char/2.cc
Normal 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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
72
libstdc++-v3/testsuite/27_io/basic_ostream/put/char/1.cc
Normal file
72
libstdc++-v3/testsuite/27_io/basic_ostream/put/char/1.cc
Normal 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;
|
||||
}
|
73
libstdc++-v3/testsuite/27_io/basic_ostream/write/char/1.cc
Normal file
73
libstdc++-v3/testsuite/27_io/basic_ostream/write/char/1.cc
Normal 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;
|
||||
}
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user