[Patch] Fix libstdc++/9561
Jerry Quinn
jlquinn@optonline.net
Tue Feb 25 04:33:00 GMT 2003
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=9561
The testcase throws an exception foobar, which gets caught here:
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
basic_ostream<_CharT, _Traits>::
operator<<(__ios_type& (*__pf)(__ios_type&))
{
sentry __cerb(*this);
if (__cerb)
{
try
{ __pf(*this); }
catch(exception& __fail)
{
this->setstate(ios_base::badbit);
if ((this->exceptions() & ios_base::badbit) != 0)
__throw_exception_again;
}
}
return *this;
}
The problem is that the exception mask for badbit is on, and setstate() throws
its own exception rather than rethrowing the one already thrown.
The solution is to provide a non-throwing means of setting the badbit flag in
the formatted output routines.
2003-02-24 Jerry Quinn <jlquinn@us.ibm.com>
* include/bits/basic_ios.h (_M_setstate): New.
* include/bits/ostream.tcc (operator<<): Use it.
* include/std/std_ostream.h (operator<<): Make friends.
Index: libstdc++-v3/include/bits/basic_ios.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/basic_ios.h,v
retrieving revision 1.17
diff -u -r1.17 basic_ios.h
--- libstdc++-v3/include/bits/basic_ios.h 18 Feb 2003 05:45:06 -0000 1.17
+++ libstdc++-v3/include/bits/basic_ios.h 25 Feb 2003 04:18:19 -0000
@@ -441,6 +441,11 @@
void
_M_cache_locale(const locale& __loc);
+
+ // Internal state setter that won't throw, only set the state bits.
+ // Used to guarantee we don't throw when setting badbit.
+ void
+ _M_setstate(iostate __state) { _M_streambuf_state |= __state; }
};
} // namespace std
Index: libstdc++-v3/include/bits/ostream.tcc
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/bits/ostream.tcc,v
retrieving revision 1.36
diff -u -r1.36 ostream.tcc
--- libstdc++-v3/include/bits/ostream.tcc 13 Feb 2003 21:39:03 -0000 1.36
+++ libstdc++-v3/include/bits/ostream.tcc 25 Feb 2003 04:18:20 -0000
@@ -70,7 +70,7 @@
{
// 27.6.2.5.1 Common requirements.
// Turn this on without causing an ios::failure to be thrown.
- this->setstate(ios_base::badbit);
+ this->_M_setstate(ios_base::badbit);
if ((this->exceptions() & ios_base::badbit) != 0)
__throw_exception_again;
}
@@ -92,7 +92,7 @@
{
// 27.6.2.5.1 Common requirements.
// Turn this on without causing an ios::failure to be thrown.
- this->setstate(ios_base::badbit);
+ this->_M_setstate(ios_base::badbit);
if ((this->exceptions() & ios_base::badbit) != 0)
__throw_exception_again;
}
@@ -114,7 +114,7 @@
{
// 27.6.2.5.1 Common requirements.
// Turn this on without causing an ios::failure to be thrown.
- this->setstate(ios_base::badbit);
+ this->_M_setstate(ios_base::badbit);
if ((this->exceptions() & ios_base::badbit) != 0)
__throw_exception_again;
}
@@ -138,7 +138,7 @@
{
// 27.6.2.5.1 Common requirements.
// Turn this on without causing an ios::failure to be thrown.
- this->setstate(ios_base::badbit);
+ this->_M_setstate(ios_base::badbit);
if ((this->exceptions() & ios_base::badbit) != 0)
__throw_exception_again;
}
@@ -166,7 +166,7 @@
{
// 27.6.1.2.1 Common requirements.
// Turn this on without causing an ios::failure to be thrown.
- this->setstate(ios_base::badbit);
+ this->_M_setstate(ios_base::badbit);
if ((this->exceptions() & ios_base::badbit) != 0)
__throw_exception_again;
}
@@ -205,7 +205,7 @@
{
// 27.6.1.2.1 Common requirements.
// Turn this on without causing an ios::failure to be thrown.
- this->setstate(ios_base::badbit);
+ this->_M_setstate(ios_base::badbit);
if ((this->exceptions() & ios_base::badbit) != 0)
__throw_exception_again;
}
@@ -231,7 +231,7 @@
{
// 27.6.1.2.1 Common requirements.
// Turn this on without causing an ios::failure to be thrown.
- this->setstate(ios_base::badbit);
+ this->_M_setstate(ios_base::badbit);
if ((this->exceptions() & ios_base::badbit) != 0)
__throw_exception_again;
}
@@ -272,7 +272,7 @@
{
// 27.6.1.2.1 Common requirements.
// Turn this on without causing an ios::failure to be thrown.
- this->setstate(ios_base::badbit);
+ this->_M_setstate(ios_base::badbit);
if ((this->exceptions() & ios_base::badbit) != 0)
__throw_exception_again;
}
@@ -298,7 +298,7 @@
{
// 27.6.1.2.1 Common requirements.
// Turn this on without causing an ios::failure to be thrown.
- this->setstate(ios_base::badbit);
+ this->_M_setstate(ios_base::badbit);
if ((this->exceptions() & ios_base::badbit) != 0)
__throw_exception_again;
}
@@ -325,7 +325,7 @@
{
// 27.6.1.2.1 Common requirements.
// Turn this on without causing an ios::failure to be thrown.
- this->setstate(ios_base::badbit);
+ this->_M_setstate(ios_base::badbit);
if ((this->exceptions() & ios_base::badbit) != 0)
__throw_exception_again;
}
@@ -351,7 +351,7 @@
{
// 27.6.1.2.1 Common requirements.
// Turn this on without causing an ios::failure to be thrown.
- this->setstate(ios_base::badbit);
+ this->_M_setstate(ios_base::badbit);
if ((this->exceptions() & ios_base::badbit) != 0)
__throw_exception_again;
}
@@ -377,7 +377,7 @@
{
// 27.6.1.2.1 Common requirements.
// Turn this on without causing an ios::failure to be thrown.
- this->setstate(ios_base::badbit);
+ this->_M_setstate(ios_base::badbit);
if ((this->exceptions() & ios_base::badbit) != 0)
__throw_exception_again;
}
@@ -499,7 +499,7 @@
{
// 27.6.1.2.1 Common requirements.
// Turn this on without causing an ios::failure to be thrown.
- __out.setstate(ios_base::badbit);
+ __out._M_setstate(ios_base::badbit);
if ((__out.exceptions() & ios_base::badbit) != 0)
__throw_exception_again;
}
@@ -535,7 +535,7 @@
{
// 27.6.1.2.1 Common requirements.
// Turn this on without causing an ios::failure to be thrown.
- __out.setstate(ios_base::badbit);
+ __out._M_setstate(ios_base::badbit);
if ((__out.exceptions() & ios_base::badbit) != 0)
__throw_exception_again;
}
@@ -570,7 +570,7 @@
{
// 27.6.1.2.1 Common requirements.
// Turn this on without causing an ios::failure to be thrown.
- __out.setstate(ios_base::badbit);
+ __out._M_setstate(ios_base::badbit);
if ((__out.exceptions() & ios_base::badbit) != 0)
__throw_exception_again;
}
@@ -619,7 +619,7 @@
{
// 27.6.1.2.1 Common requirements.
// Turn this on without causing an ios::failure to be thrown.
- __out.setstate(ios_base::badbit);
+ __out._M_setstate(ios_base::badbit);
if ((__out.exceptions() & ios_base::badbit) != 0)
__throw_exception_again;
}
@@ -658,7 +658,7 @@
{
// 27.6.1.2.1 Common requirements.
// Turn this on without causing an ios::failure to be thrown.
- __out.setstate(ios_base::badbit);
+ __out._M_setstate(ios_base::badbit);
if ((__out.exceptions() & ios_base::badbit) != 0)
__throw_exception_again;
}
Index: libstdc++-v3/include/std/std_ostream.h
===================================================================
RCS file: /cvsroot/gcc/gcc/libstdc++-v3/include/std/std_ostream.h,v
retrieving revision 1.7
diff -u -r1.7 std_ostream.h
--- libstdc++-v3/include/std/std_ostream.h 7 Feb 2003 00:26:44 -0000 1.7
+++ libstdc++-v3/include/std/std_ostream.h 25 Feb 2003 04:18:21 -0000
@@ -73,6 +73,10 @@
typedef num_put<_CharT, __ostreambuf_iter> __numput_type;
typedef ctype<_CharT> __ctype_type;
+ friend __ostream_type& operator<< <>(__ostream_type& __out, _CharT __c);
+ friend __ostream_type& operator<< <>(__ostream_type& __out, const _CharT* __s);
+ friend __ostream_type& operator<< <>(__ostream_type& __out, const char* __s);
+
// [27.6.2.2] constructor/destructor
/**
* @brief Base constructor.
More information about the Gcc-patches
mailing list