+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>
* config/locale/ieee_1003.1-2001/codecvt_specializations.h
* libsupc++/eh_personality.cc (__cxa_call_unexpected): Copy handler
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
g++ builtins, use the double variants from the global namespace
basic_ostream<_CharT, _Traits>* _M_tie;
mutable char_type _M_fill;
mutable bool _M_fill_init;
- iostate _M_exception;
-
basic_streambuf<_CharT, _Traits>* _M_streambuf;
- iostate _M_streambuf_state;
// Cached use_facet<ctype>, which is based on the current locale info.
const __ctype_type* _M_ios_fctype;
// associated with imbue()
// Alloc any new word array first, so if it fails we have "rollback".
- _Words* __words = (__rhs._M_word_limit <= _S_local_words) ?
- _M_word_array : new _Words[__rhs._M_word_limit];
+ _Words* __words = (__rhs._M_word_size <= _S_local_word_size) ?
+ _M_local_word : new _Words[__rhs._M_word_size];
// XXX This is the only reason _Callback_list was defined
// inline. The suspicion is that this increased compilation
if (__cb)
__cb->_M_add_reference();
_M_call_callbacks(erase_event);
- if (_M_words != _M_word_array)
- delete [] _M_words;
+ if (_M_word != _M_local_word)
+ {
+ delete [] _M_word;
+ _M_word = 0;
+ }
_M_dispose_callbacks();
_M_callbacks = __cb; // NB: Don't want any added during above.
- for (int __i = 0; __i < __rhs._M_word_limit; ++__i)
- __words[__i] = __rhs._M_words[__i];
- if (_M_words != _M_word_array)
- delete [] _M_words;
- _M_words = __words;
- _M_word_limit = __rhs._M_word_limit;
+ for (int __i = 0; __i < __rhs._M_word_size; ++__i)
+ __words[__i] = __rhs._M_word[__i];
+ if (_M_word != _M_local_word)
+ {
+ delete [] _M_word;
+ _M_word = 0;
+ }
+ _M_word = __words;
+ _M_word_size = __rhs._M_word_size;
this->flags(__rhs.flags());
this->width(__rhs.width());
_CharT*
_M_refdata() throw()
- { return reinterpret_cast<_CharT*> (this + 1); }
+ { return reinterpret_cast<_CharT*>(this + 1); }
_CharT&
operator[](size_t __s) throw()
_CharT*
_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
static _Rep*
explicit
failure(const string& __str) throw();
+ // This declaration is not useless:
+ // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
virtual
~failure() throw();
streamsize _M_precision;
streamsize _M_width;
fmtflags _M_flags;
+ iostate _M_exception;
+ iostate _M_streambuf_state;
// 27.4.2.6 Members for callbacks
// 27.4.2.6 ios_base callbacks
void
_M_add_reference() { __atomic_add(&_M_refcount, 1); }
+ // 0 => OK to delete.
int
_M_remove_reference() { return __exchange_and_add(&_M_refcount, -1); }
- // 0 => OK to delete
};
_Callback_list* _M_callbacks;
{
void* _M_pword;
long _M_iword;
+ _Words() : _M_pword(0), _M_iword(0) { }
};
- 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;
+ // Only for failed iword/pword calls.
+ _Words _M_word_zero;
+
+ // Guaranteed storage.
+ 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&
_M_grow_words(int __index);
inline long&
iword(int __ix)
{
- _Words& __word = (__ix < _M_word_limit)
- ? _M_words[__ix] : _M_grow_words(__ix);
+ _Words& __word = (__ix < _M_word_size)
+ ? _M_word[__ix] : _M_grow_words(__ix);
return __word._M_iword;
}
inline void*&
pword(int __ix)
{
- _Words& __word = (__ix < _M_word_limit)
- ? _M_words[__ix] : _M_grow_words(__ix);
+ _Words& __word = (__ix < _M_word_size)
+ ? _M_word[__ix] : _M_grow_words(__ix);
return __word._M_pword;
}
try
{
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;
streamsize __len = 1;
if (__w > __len)
const ios_base::seekdir ios_base::cur;
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;
bool ios_base::Init::_S_synced_with_stdio = true;
int
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
// 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
ios_base::_Words&
ios_base::_M_grow_words(int ix)
{
- // Precondition: _M_word_limit <= ix
- _Words zero = { 0, 0 };
- int newlimit = _S_local_words;
- _Words* words = _M_word_array;
+ // Precondition: _M_word_size <= ix
+ int newsize = _S_local_word_size;
+ _Words* words = _M_local_word;
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
- { words = new _Words[ix+1]; }
+ { words = new _Words[newsize]; }
catch (...)
{
- _M_dummy = zero; // XXX MT? Not on "normal" machines.
- // XXX now in basic_ios
- // _M_clear(_M_rdstate() | badbit); // may throw
- return _M_dummy;
+ delete [] _M_word;
+ _M_word = 0;
+ _M_streambuf_state |= badbit;
+ 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;
}
-
- do { words[i] = zero; } while (++i < newlimit);
- _M_words = words;
- _M_word_limit = newlimit;
- return words[ix];
+ _M_word = words;
+ _M_word_size = newsize;
+ return _M_word[ix];
}
// Called only by basic_ios<>::init.
_M_width = 0;
_M_flags = skipws | dec;
_M_callbacks = 0;
- _M_words = 0;
- _M_word_limit = 0;
+ _M_word_size = 0;
_M_ios_locale = locale();
- // No init needed for _M_word_array or _M_dummy.
}
// 27.4.2.3 ios_base locale functions
return __old;
}
- ios_base::ios_base()
+ ios_base::ios_base() : _M_callbacks(0), _M_word(0)
{
// 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.
- _M_callbacks = 0;
- _M_words = 0;
}
// 27.4.2.7 ios_base constructors/destructors
{
_M_call_callbacks(erase_event);
_M_dispose_callbacks();
- if (_M_words && _M_words != _M_word_array)
- delete [] _M_words;
+ if (_M_word && _M_word != _M_local_word)
+ {
+ delete [] _M_word;
+ _M_word = 0;
+ }
}
void
// 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
// software; you can redistribute it and/or modify it under the
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)
{
test01();
-
+ test02();
return 0;
}