[v3] PR 11584
Jerry Quinn
jlquinn@optonline.net
Tue Jan 27 02:39:00 GMT 2004
This patch fixes PR 11584. The catch here is the standard is somewhat
underspecified. The testcase checks iword(100), because in our
implementation, iword(1) will always succeed. The way I read the
standard, this is ok, since even though new is overridden, the
allocation of space for iword(1) didn't fail.
Martin, does this solution make sense to you?
Jerry
2004-01-26 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.
Index: include/bits/ios_base.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/ios_base.h,v
retrieving revision 1.37
diff -u -w -r1.37 ios_base.h
--- include/bits/ios_base.h 22 Dec 2003 20:09:21 -0000 1.37
+++ include/bits/ios_base.h 27 Jan 2004 02:19:19 -0000
@@ -471,7 +471,7 @@
_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 @@
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 @@
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;
}
Index: src/ios.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/ios.cc,v
retrieving revision 1.52
diff -u -w -r1.52 ios.cc
--- src/ios.cc 15 Dec 2003 19:03:12 -0000 1.52
+++ src/ios.cc 27 Jan 2004 02:19:22 -0000
@@ -147,7 +147,7 @@
// 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,8 @@
if (_M_streambuf_state & _M_exception)
__throw_ios_failure("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,7 +182,9 @@
_M_streambuf_state |= badbit;
if (_M_streambuf_state & _M_exception)
__throw_ios_failure("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;
}
}
--- testsuite/27_io/ios_base/storage/empty 1969-12-31 19:00:00.000000000 -0500
+++ testsuite/27_io/ios_base/storage/11584.cc 2004-01-25 21:07:19.000000000 -0500
@@ -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;
+}
+
More information about the Gcc-patches
mailing list