[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