This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[v3] ios_base dtor cleanups
- From: Benjamin Kosnik <bkoz at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 25 Feb 2002 20:45:47 -0800
- Subject: [v3] ios_base dtor cleanups
While looking again at the _M_fill issue, I noticed a problem with the
testcase I gave as an example of standards-conformant behavior. When I
fixed that, I noticed something else was wrong..... and so it goes.
tested x86/linux
2002-02-25 Benjamin Kosnik <bkoz@redhat.com>
* src/ios.cc (ios_base::~ios_base): Tweak.
(ios_base::_M_call_callbacks): Deal with null __p.
(ios_base::ios_base): Set _M_callbacks.
* include/bits/basic_ios.tcc (basic_ios::init): Adjust comment.
* testsuite/27_io/ios_init.cc (test02): Fix.
* mkcheck.in (static_fail): Failed links go to output file.
Index: mkcheck.in
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/mkcheck.in,v
retrieving revision 1.61
diff -c -p -r1.61 mkcheck.in
*** mkcheck.in 2001/10/19 23:05:15 1.61
--- mkcheck.in 2002/02/26 04:43:01
*************** test_file()
*** 362,369 ****
else
# the file did not compile/link.
printf "\n" >> $LOG_FILE
! # `cat compile.out >> $LOG_FILE`
! # rm compile.out
RESULT="-b"
TEXT="0"
DATA="0"
--- 362,369 ----
else
# the file did not compile/link.
printf "\n" >> $LOG_FILE
! `cat compile.out >> $LOG_FILE`
! rm compile.out
RESULT="-b"
TEXT="0"
DATA="0"
Index: include/bits/basic_ios.tcc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/basic_ios.tcc,v
retrieving revision 1.11
diff -c -p -r1.11 basic_ios.tcc
*** basic_ios.tcc 2002/02/16 19:33:43 1.11
--- basic_ios.tcc 2002/02/26 04:43:04
*************** namespace std
*** 148,159 ****
// requirements after basic_ios::init() has been called. As part
// of this, fill() must return widen(' '), which needs an imbued
// ctype facet of char_type to return without throwing an
! // exception. This is not a required facet, so streams with
! // char_type != [char, wchar_t] will not have it by
! // default. However, because fill()'s signature is const, this
! // data member cannot be lazily initialized. Thus, thoughts of
! // using a non-const helper function in ostream inserters is
! // really besides the point.
_M_fill = this->widen(' ');
_M_exception = goodbit;
--- 148,159 ----
// requirements after basic_ios::init() has been called. As part
// of this, fill() must return widen(' '), which needs an imbued
// ctype facet of char_type to return without throwing an
! // exception. Unfortunately, ctype<char_type> is not necessarily a
! // required facet, so streams with char_type != [char, wchar_t]
! // will not have it by default. However, because fill()'s
! // signature is const, this data member cannot be lazily
! // initialized. Thus, thoughts of using a non-const helper
! // function in ostream inserters is really besides the point.
_M_fill = this->widen(' ');
_M_exception = goodbit;
Index: include/bits/ios_base.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/ios_base.h,v
retrieving revision 1.15
diff -c -p -r1.15 ios_base.h
*** ios_base.h 2002/01/24 21:14:37 1.15
--- ios_base.h 2002/02/26 04:43:04
*************** namespace std
*** 277,283 ****
};
static const int _S_local_words = 8;
! _Words _M_word_array[_S_local_words]; // Guaranteed storage
_Words _M_dummy; // Only for failed iword/pword calls.
_Words* _M_words;
int _M_word_limit;
--- 277,283 ----
};
static const int _S_local_words = 8;
! _Words _M_word_array[_S_local_words]; // Guaranteed storage.
_Words _M_dummy; // Only for failed iword/pword calls.
_Words* _M_words;
int _M_word_limit;
Index: src/ios.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/ios.cc,v
retrieving revision 1.24
diff -c -p -r1.24 ios.cc
*** ios.cc 2002/01/24 21:14:40 1.24
--- ios.cc 2002/02/26 04:43:06
*************** namespace std
*** 257,263 ****
}
for (; i < _M_word_limit; i++)
words[i] = _M_words[i];
! if (_M_words != _M_word_array)
delete [] _M_words;
}
--- 257,263 ----
}
for (; i < _M_word_limit; i++)
words[i] = _M_words[i];
! if (_M_words && _M_words != _M_word_array)
delete [] _M_words;
}
*************** namespace std
*** 294,300 ****
ios_base::ios_base()
{
! // Do nothing; init() does it. Static init to 0 makes everything sane.
}
// 27.4.2.7 ios_base constructors/destructors
--- 294,304 ----
ios_base::ios_base()
{
! // Do nothing: basic_ios::init() does it.
! // NB: _M_callbacks and _M_words must be zero for non-initialized
! // ios_base to go through ~ios_base gracefully.
! _M_callbacks = 0;
! _M_words = 0;
}
// 27.4.2.7 ios_base constructors/destructors
*************** namespace std
*** 302,310 ****
{
_M_call_callbacks(erase_event);
_M_dispose_callbacks();
! if (_M_words != _M_word_array)
delete [] _M_words;
- // XXX done?
}
void
--- 306,313 ----
{
_M_call_callbacks(erase_event);
_M_dispose_callbacks();
! if (_M_words && _M_words != _M_word_array)
delete [] _M_words;
}
void
*************** namespace std
*** 314,326 ****
void
ios_base::_M_call_callbacks(event __e) throw()
{
! for (_Callback_list* __p = _M_callbacks; __p; __p = __p->_M_next)
{
! try {
! (*__p->_M_fn) (__e, *this, __p->_M_index);
! }
! catch (...) {
! }
}
}
--- 317,330 ----
void
ios_base::_M_call_callbacks(event __e) throw()
{
! _Callback_list* __p = _M_callbacks;
! while (__p)
{
! try
! { (*__p->_M_fn) (__e, *this, __p->_M_index); }
! catch (...)
! { }
! __p = __p->_M_next;
}
}
Index: testsuite/27_io/ios_init.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/27_io/ios_init.cc,v
retrieving revision 1.4
diff -c -p -r1.4 ios_init.cc
*** ios_init.cc 2002/02/20 00:58:17 1.4
--- ios_init.cc 2002/02/26 04:43:08
*************** void test01()
*** 86,91 ****
--- 86,94 ----
// by default, into the locale object. As such, basic_ios::init is
// required to return a bad_cast for the first use of fill() call.
// See 27.4.4.1
+
+ class gnu_ios: public std::basic_ios<char> { };
+
void test02()
{
bool test = true;
*************** void test02()
*** 93,99 ****
// 01: Doesn't call basic_ios::init, which uses ctype<char_type>..
try
{
! std::basic_ostringstream<unsigned short> oss;
}
catch(...)
{
--- 96,102 ----
// 01: Doesn't call basic_ios::init, which uses ctype<char_type>..
try
{
! gnu_ios gios;
}
catch(...)
{
*************** void test02()
*** 122,128 ****
}
catch(const std::bad_cast& obj)
{
! test = true;
}
catch(...)
{
--- 125,131 ----
}
catch(const std::bad_cast& obj)
{
! // This is correct.
}
catch(...)
{