From 2a837cf80316570aaad5bf93b10655bb62ae67ad Mon Sep 17 00:00:00 2001 From: Jerry Quinn Date: Tue, 27 Jan 2004 15:45:43 +0000 Subject: [PATCH] re PR libstdc++/11584 (ios::iword() fails to zero-initialize storage on failure) 2004-01-27 Jerry Quinn PR libstdc++/11584 * include/bits/ios_base.h (ios_base::_M_grow_words): Add iword/pword selector. (ios_base::iword, ios_base::pword): Use it. * src/ios.cc (ios_base::_M_grow_words): Clear _M_word_zero iword or pword member on alloc failure. * testsuite/27_io/ios_base/storage/11584.cc: New test. From-SVN: r76725 --- libstdc++-v3/ChangeLog | 10 +++ libstdc++-v3/include/bits/ios_base.h | 6 +- libstdc++-v3/src/ios.cc | 10 ++- .../testsuite/27_io/ios_base/storage/11584.cc | 61 +++++++++++++++++++ 4 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 libstdc++-v3/testsuite/27_io/ios_base/storage/11584.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index ea093c2c9aa..65c10db3f2d 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,13 @@ +2004-01-27 Jerry Quinn + + PR libstdc++/11584 + * include/bits/ios_base.h (ios_base::_M_grow_words): Add + iword/pword selector. + (ios_base::iword, ios_base::pword): Use it. + * src/ios.cc (ios_base::_M_grow_words): Clear _M_word_zero + iword or pword member on alloc failure. + * testsuite/27_io/ios_base/storage/11584.cc: New test. + 2004-01-27 Ulrich Weigand PJ Darcy diff --git a/libstdc++-v3/include/bits/ios_base.h b/libstdc++-v3/include/bits/ios_base.h index 587bda4b092..b937ac5c567 100644 --- a/libstdc++-v3/include/bits/ios_base.h +++ b/libstdc++-v3/include/bits/ios_base.h @@ -471,7 +471,7 @@ namespace std _Words* _M_word; _Words& - _M_grow_words(int __index); + _M_grow_words(int __index, bool __iword); // Members for locale and locale caching. locale _M_ios_locale; @@ -692,7 +692,7 @@ namespace std iword(int __ix) { _Words& __word = (__ix < _M_word_size) - ? _M_word[__ix] : _M_grow_words(__ix); + ? _M_word[__ix] : _M_grow_words(__ix, true); return __word._M_iword; } @@ -713,7 +713,7 @@ namespace std pword(int __ix) { _Words& __word = (__ix < _M_word_size) - ? _M_word[__ix] : _M_grow_words(__ix); + ? _M_word[__ix] : _M_grow_words(__ix, false); return __word._M_pword; } diff --git a/libstdc++-v3/src/ios.cc b/libstdc++-v3/src/ios.cc index 0dec32358c2..6f987c22395 100644 --- a/libstdc++-v3/src/ios.cc +++ b/libstdc++-v3/src/ios.cc @@ -147,7 +147,7 @@ namespace std // 27.4.2.5 iword/pword storage ios_base::_Words& - ios_base::_M_grow_words(int ix) + ios_base::_M_grow_words(int ix, bool iword) { // Precondition: _M_word_size <= ix int newsize = _S_local_word_size; @@ -165,6 +165,10 @@ namespace std if (_M_streambuf_state & _M_exception) __throw_ios_failure(__N("ios_base::_M_grow_words " "allocation failed")); + if (iword) + _M_word_zero._M_iword = 0; + else + _M_word_zero._M_pword = 0; return _M_word_zero; } for (int i = 0; i < _M_word_size; i++) @@ -180,6 +184,10 @@ namespace std _M_streambuf_state |= badbit; if (_M_streambuf_state & _M_exception) __throw_ios_failure(__N("ios_base::_M_grow_words is not valid")); + if (iword) + _M_word_zero._M_iword = 0; + else + _M_word_zero._M_pword = 0; return _M_word_zero; } } diff --git a/libstdc++-v3/testsuite/27_io/ios_base/storage/11584.cc b/libstdc++-v3/testsuite/27_io/ios_base/storage/11584.cc new file mode 100644 index 00000000000..8b1a7a72d96 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/ios_base/storage/11584.cc @@ -0,0 +1,61 @@ +// 2004-01-25 jlquinn@gcc.gnu.org + +// Copyright (C) 2004 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.4.2.5 ios_base storage functions + +#include +#include +#include + +int new_fails; + +void* operator new (size_t n) +{ + if (new_fails) + throw std::bad_alloc(); + + return malloc(n); +} + +void operator delete (void *p) { free(p); } +void* operator new[] (size_t n) { return operator new(n); } +void operator delete[] (void *p) { operator delete(p); } + +int main () +{ + const int i = std::ios::xalloc (); + + new_fails = 1; + + // Successive accesses to failure storage clears to zero. + std::cout.iword(100) = 0xdeadbeef; + VERIFY(std::cout.iword(100) == 0); + + // Access to pword failure storage shouldn't clear iword pword storage. + long& lr = std::cout.iword(100); + lr = 0xdeadbeef; + + void* pv = std::cout.pword(100); + VERIFY(pv == 0); + VERIFY(lr == 0xdeadbeef); + + return 0; +} +