re PR libstdc++/11584 (ios::iword() fails to zero-initialize storage on failure)

2004-01-27  Jerry Quinn  <jlquinn@optonline.net>

	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
This commit is contained in:
Jerry Quinn 2004-01-27 15:45:43 +00:00 committed by Jerry Quinn
parent 6e198ee05d
commit 2a837cf803
4 changed files with 83 additions and 4 deletions

View File

@ -1,3 +1,13 @@
2004-01-27 Jerry Quinn <jlquinn@optonline.net>
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 <uweigand@de.ibm.com>
PJ Darcy <darcypj@us.ibm.com>

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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 <cstdlib>
#include <new>
#include <testsuite_hooks.h>
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;
}