Commit 663653eb by Benjamin Kosnik

basic_ios.h (basic_ios::_M_exception): Move.


2002-04-01  Benjamin Kosnik  <bkoz@redhat.com>

	libstdc++/3129
	* include/bits/basic_ios.h (basic_ios::_M_exception): Move.
	(basic_ios::_M_streambuf_state): Move.
	* include/bits/ios_base (ios_base): To here.
	* include/bits/ios_base.h (ios_base::_S_local_words): To
	_S_local_word_size.
	(ios_base::_M_word_array): To _M_local_word.
	(ios_base::_M_words_limit): To _M_word_size.
	(ios_base::_M_words): To _M_word.
	Comment.
	* include/bits/basic_ios.tcc: Adjust.
	* src/ios.cc (ios_base::_M_grow_words): Tweak.
	* testsuite/27_io/ios_base_storage.cc: Add tests.

	libstdc++/5207
	Kenny Simpson <theonetruekenny@yahoo.com>
	* include/bits/ios_base.h: Fix.

	Richard Henderson  <rth@redhat.com>
	* include/bits/ostream.tcc (ostream::operator<<(_CharT)): Correct
	last change.

	* include/bits/basic_string.h: Tweak formatting.

From-SVN: r51695
parent 55173836
2002-04-01 Benjamin Kosnik <bkoz@redhat.com>
libstdc++/3129
* include/bits/basic_ios.h (basic_ios::_M_exception): Move.
(basic_ios::_M_streambuf_state): Move.
* include/bits/ios_base (ios_base): To here.
* include/bits/ios_base.h (ios_base::_S_local_words): To
_S_local_word_size.
(ios_base::_M_word_array): To _M_local_word.
(ios_base::_M_words_limit): To _M_word_size.
(ios_base::_M_words): To _M_word.
Comment.
* include/bits/basic_ios.tcc: Adjust.
* src/ios.cc (ios_base::_M_grow_words): Tweak.
* testsuite/27_io/ios_base_storage.cc: Add tests.
libstdc++/5207
Kenny Simpson <theonetruekenny@yahoo.com>
* include/bits/ios_base.h: Fix.
Richard Henderson <rth@redhat.com>
* include/bits/ostream.tcc (ostream::operator<<(_CharT)): Correct
last change.
* include/bits/basic_string.h: Tweak formatting.
2002-04-01 Paolo Carlini <pcarlini@unitus.it> 2002-04-01 Paolo Carlini <pcarlini@unitus.it>
* config/locale/ieee_1003.1-2001/codecvt_specializations.h * config/locale/ieee_1003.1-2001/codecvt_specializations.h
...@@ -14,7 +40,7 @@ ...@@ -14,7 +40,7 @@
* libsupc++/eh_personality.cc (__cxa_call_unexpected): Copy handler * libsupc++/eh_personality.cc (__cxa_call_unexpected): Copy handler
data out of the exception struct before calling unexpectedHandler. data out of the exception struct before calling unexpectedHandler.
2002-03-27 Roger Sayle <roger@eyesopen.com> 2002-03-28 Roger Sayle <roger@eyesopen.com>
* include/c_std/std_cmath.h: To prevent problems overloading * include/c_std/std_cmath.h: To prevent problems overloading
g++ builtins, use the double variants from the global namespace g++ builtins, use the double variants from the global namespace
......
...@@ -66,10 +66,7 @@ namespace std ...@@ -66,10 +66,7 @@ namespace std
basic_ostream<_CharT, _Traits>* _M_tie; basic_ostream<_CharT, _Traits>* _M_tie;
mutable char_type _M_fill; mutable char_type _M_fill;
mutable bool _M_fill_init; mutable bool _M_fill_init;
iostate _M_exception;
basic_streambuf<_CharT, _Traits>* _M_streambuf; basic_streambuf<_CharT, _Traits>* _M_streambuf;
iostate _M_streambuf_state;
// Cached use_facet<ctype>, which is based on the current locale info. // Cached use_facet<ctype>, which is based on the current locale info.
const __ctype_type* _M_ios_fctype; const __ctype_type* _M_ios_fctype;
......
...@@ -64,8 +64,8 @@ namespace std ...@@ -64,8 +64,8 @@ namespace std
// associated with imbue() // associated with imbue()
// Alloc any new word array first, so if it fails we have "rollback". // Alloc any new word array first, so if it fails we have "rollback".
_Words* __words = (__rhs._M_word_limit <= _S_local_words) ? _Words* __words = (__rhs._M_word_size <= _S_local_word_size) ?
_M_word_array : new _Words[__rhs._M_word_limit]; _M_local_word : new _Words[__rhs._M_word_size];
// XXX This is the only reason _Callback_list was defined // XXX This is the only reason _Callback_list was defined
// inline. The suspicion is that this increased compilation // inline. The suspicion is that this increased compilation
...@@ -78,17 +78,23 @@ namespace std ...@@ -78,17 +78,23 @@ namespace std
if (__cb) if (__cb)
__cb->_M_add_reference(); __cb->_M_add_reference();
_M_call_callbacks(erase_event); _M_call_callbacks(erase_event);
if (_M_words != _M_word_array) if (_M_word != _M_local_word)
delete [] _M_words; {
delete [] _M_word;
_M_word = 0;
}
_M_dispose_callbacks(); _M_dispose_callbacks();
_M_callbacks = __cb; // NB: Don't want any added during above. _M_callbacks = __cb; // NB: Don't want any added during above.
for (int __i = 0; __i < __rhs._M_word_limit; ++__i) for (int __i = 0; __i < __rhs._M_word_size; ++__i)
__words[__i] = __rhs._M_words[__i]; __words[__i] = __rhs._M_word[__i];
if (_M_words != _M_word_array) if (_M_word != _M_local_word)
delete [] _M_words; {
_M_words = __words; delete [] _M_word;
_M_word_limit = __rhs._M_word_limit; _M_word = 0;
}
_M_word = __words;
_M_word_size = __rhs._M_word_size;
this->flags(__rhs.flags()); this->flags(__rhs.flags());
this->width(__rhs.width()); this->width(__rhs.width());
......
...@@ -162,7 +162,7 @@ namespace std ...@@ -162,7 +162,7 @@ namespace std
_CharT* _CharT*
_M_refdata() throw() _M_refdata() throw()
{ return reinterpret_cast<_CharT*> (this + 1); } { return reinterpret_cast<_CharT*>(this + 1); }
_CharT& _CharT&
operator[](size_t __s) throw() operator[](size_t __s) throw()
...@@ -170,8 +170,10 @@ namespace std ...@@ -170,8 +170,10 @@ namespace std
_CharT* _CharT*
_M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2) _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2)
{ return (!_M_is_leaked() && __alloc1 == __alloc2) ? {
_M_refcopy() : _M_clone(__alloc1); } return (!_M_is_leaked() && __alloc1 == __alloc2)
? _M_refcopy() : _M_clone(__alloc1);
}
// Create & Destroy // Create & Destroy
static _Rep* static _Rep*
......
...@@ -158,6 +158,8 @@ namespace std ...@@ -158,6 +158,8 @@ namespace std
explicit explicit
failure(const string& __str) throw(); failure(const string& __str) throw();
// This declaration is not useless:
// http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
virtual virtual
~failure() throw(); ~failure() throw();
...@@ -238,6 +240,8 @@ namespace std ...@@ -238,6 +240,8 @@ namespace std
streamsize _M_precision; streamsize _M_precision;
streamsize _M_width; streamsize _M_width;
fmtflags _M_flags; fmtflags _M_flags;
iostate _M_exception;
iostate _M_streambuf_state;
// 27.4.2.6 Members for callbacks // 27.4.2.6 Members for callbacks
// 27.4.2.6 ios_base callbacks // 27.4.2.6 ios_base callbacks
...@@ -256,9 +260,9 @@ namespace std ...@@ -256,9 +260,9 @@ namespace std
void void
_M_add_reference() { __atomic_add(&_M_refcount, 1); } _M_add_reference() { __atomic_add(&_M_refcount, 1); }
// 0 => OK to delete.
int int
_M_remove_reference() { return __exchange_and_add(&_M_refcount, -1); } _M_remove_reference() { return __exchange_and_add(&_M_refcount, -1); }
// 0 => OK to delete
}; };
_Callback_list* _M_callbacks; _Callback_list* _M_callbacks;
...@@ -274,13 +278,19 @@ namespace std ...@@ -274,13 +278,19 @@ namespace std
{ {
void* _M_pword; void* _M_pword;
long _M_iword; long _M_iword;
_Words() : _M_pword(0), _M_iword(0) { }
}; };
static const int _S_local_words = 8; // Only for failed iword/pword calls.
_Words _M_word_array[_S_local_words]; // Guaranteed storage. _Words _M_word_zero;
_Words _M_dummy; // Only for failed iword/pword calls.
_Words* _M_words; // Guaranteed storage.
int _M_word_limit; static const int _S_local_word_size = 8;
_Words _M_local_word[_S_local_word_size];
// Allocated storage.
int _M_word_size;
_Words* _M_word;
_Words& _Words&
_M_grow_words(int __index); _M_grow_words(int __index);
...@@ -386,16 +396,16 @@ namespace std ...@@ -386,16 +396,16 @@ namespace std
inline long& inline long&
iword(int __ix) iword(int __ix)
{ {
_Words& __word = (__ix < _M_word_limit) _Words& __word = (__ix < _M_word_size)
? _M_words[__ix] : _M_grow_words(__ix); ? _M_word[__ix] : _M_grow_words(__ix);
return __word._M_iword; return __word._M_iword;
} }
inline void*& inline void*&
pword(int __ix) pword(int __ix)
{ {
_Words& __word = (__ix < _M_word_limit) _Words& __word = (__ix < _M_word_size)
? _M_words[__ix] : _M_grow_words(__ix); ? _M_word[__ix] : _M_grow_words(__ix);
return __word._M_pword; return __word._M_pword;
} }
......
...@@ -481,7 +481,7 @@ namespace std ...@@ -481,7 +481,7 @@ namespace std
try try
{ {
streamsize __w = __out.width(); streamsize __w = __out.width();
_CharT* __pads = static_cast<_CharT*>(__builtin_alloca((sizeof(_CharT) * __w) + 1)); _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * (__w + 1)));
__pads[0] = __c; __pads[0] = __c;
streamsize __len = 1; streamsize __len = 1;
if (__w > __len) if (__w > __len)
......
...@@ -127,7 +127,7 @@ namespace std ...@@ -127,7 +127,7 @@ namespace std
const ios_base::seekdir ios_base::cur; const ios_base::seekdir ios_base::cur;
const ios_base::seekdir ios_base::end; const ios_base::seekdir ios_base::end;
const int ios_base::_S_local_words; const int ios_base::_S_local_word_size;
int ios_base::Init::_S_ios_base_init = 0; int ios_base::Init::_S_ios_base_init = 0;
bool ios_base::Init::_S_synced_with_stdio = true; bool ios_base::Init::_S_synced_with_stdio = true;
...@@ -227,44 +227,50 @@ namespace std ...@@ -227,44 +227,50 @@ namespace std
int int
ios_base::xalloc() throw() ios_base::xalloc() throw()
{ {
// XXX should be a symbol. (Reserve 0..3 for builtins.)
static _Atomic_word top = 0;
return __exchange_and_add(&top, 1) + 4;
// Implementation note: Initialize top to zero to ensure that // Implementation note: Initialize top to zero to ensure that
// initialization occurs before main() is started. // initialization occurs before main() is started.
static _Atomic_word _S_top = 0;
return __exchange_and_add(&_S_top, 1) + 4;
} }
// 27.4.2.5 iword/pword storage // 27.4.2.5 iword/pword storage
ios_base::_Words& ios_base::_Words&
ios_base::_M_grow_words(int ix) ios_base::_M_grow_words(int ix)
{ {
// Precondition: _M_word_limit <= ix // Precondition: _M_word_size <= ix
_Words zero = { 0, 0 }; int newsize = _S_local_word_size;
int newlimit = _S_local_words; _Words* words = _M_local_word;
_Words* words = _M_word_array;
int i = 0; int i = 0;
if (_S_local_words <= ix) if (ix > _S_local_word_size - 1)
{ {
newlimit = ix+1; const int max = numeric_limits<int>::max();
if (ix < max)
newsize = ix + 1;
else
newsize = max;
try try
{ words = new _Words[ix+1]; } { words = new _Words[newsize]; }
catch (...) catch (...)
{ {
_M_dummy = zero; // XXX MT? Not on "normal" machines. delete [] _M_word;
// XXX now in basic_ios _M_word = 0;
// _M_clear(_M_rdstate() | badbit); // may throw _M_streambuf_state |= badbit;
return _M_dummy; if (_M_streambuf_state & _M_exception)
__throw_ios_failure("ios_base::_M_grow_words caused exception");
return _M_word_zero;
}
for (; i < _M_word_size; i++)
words[i] = _M_word[i];
if (_M_word && _M_word != _M_local_word)
{
delete [] _M_word;
_M_word = 0;
} }
for (; i < _M_word_limit; i++)
words[i] = _M_words[i];
if (_M_words && _M_words != _M_word_array)
delete [] _M_words;
} }
_M_word = words;
do { words[i] = zero; } while (++i < newlimit); _M_word_size = newsize;
_M_words = words; return _M_word[ix];
_M_word_limit = newlimit;
return words[ix];
} }
// Called only by basic_ios<>::init. // Called only by basic_ios<>::init.
...@@ -276,10 +282,8 @@ namespace std ...@@ -276,10 +282,8 @@ namespace std
_M_width = 0; _M_width = 0;
_M_flags = skipws | dec; _M_flags = skipws | dec;
_M_callbacks = 0; _M_callbacks = 0;
_M_words = 0; _M_word_size = 0;
_M_word_limit = 0;
_M_ios_locale = locale(); _M_ios_locale = locale();
// No init needed for _M_word_array or _M_dummy.
} }
// 27.4.2.3 ios_base locale functions // 27.4.2.3 ios_base locale functions
...@@ -292,13 +296,11 @@ namespace std ...@@ -292,13 +296,11 @@ namespace std
return __old; return __old;
} }
ios_base::ios_base() ios_base::ios_base() : _M_callbacks(0), _M_word(0)
{ {
// Do nothing: basic_ios::init() does it. // Do nothing: basic_ios::init() does it.
// NB: _M_callbacks and _M_words must be zero for non-initialized // NB: _M_callbacks and _M_word must be zero for non-initialized
// ios_base to go through ~ios_base gracefully. // ios_base to go through ~ios_base gracefully.
_M_callbacks = 0;
_M_words = 0;
} }
// 27.4.2.7 ios_base constructors/destructors // 27.4.2.7 ios_base constructors/destructors
...@@ -306,8 +308,11 @@ namespace std ...@@ -306,8 +308,11 @@ namespace std
{ {
_M_call_callbacks(erase_event); _M_call_callbacks(erase_event);
_M_dispose_callbacks(); _M_dispose_callbacks();
if (_M_words && _M_words != _M_word_array) if (_M_word && _M_word != _M_local_word)
delete [] _M_words; {
delete [] _M_word;
_M_word = 0;
}
} }
void void
......
// 2000-12-19 bkoz // 2000-12-19 bkoz
// Copyright (C) 2000 Free Software Foundation // Copyright (C) 2000, 2002 Free Software Foundation
// //
// This file is part of the GNU ISO C++ Library. This library is free // 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 // software; you can redistribute it and/or modify it under the
...@@ -41,10 +41,53 @@ void test01() ...@@ -41,10 +41,53 @@ void test01()
out.pword(++x4); // should not crash out.pword(++x4); // should not crash
} }
// libstdc++/3129
void test02()
{
bool test = true;
int max = std::numeric_limits<int>::max();
std::stringbuf strbuf;
std::ios ios(&strbuf);
long l = 0;
void* v = 0;
// pword
try
{
v = ios.pword(max);
}
catch(std::ios_base::failure& obj)
{
// Ok.
VERIFY( ios.bad() );
}
catch(...)
{
VERIFY( test = false );
}
VERIFY( v == 0 );
// iword
try
{
l = ios.iword(max);
}
catch(std::ios_base::failure& obj)
{
// Ok.
VERIFY( ios.bad() );
}
catch(...)
{
VERIFY( test = false );
}
VERIFY( l == 0 );
}
int main(void) int main(void)
{ {
test01(); test01();
test02();
return 0; return 0;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment