re PR libstdc++/11584 (ios::iword() fails to zero-initialize storage on failure)
authorJerry Quinn <jlquinn@optonline.net>
Tue, 27 Jan 2004 15:45:43 +0000 (15:45 +0000)
committerJerry Quinn <jlquinn@gcc.gnu.org>
Tue, 27 Jan 2004 15:45:43 +0000 (15:45 +0000)
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

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/ios_base.h
libstdc++-v3/src/ios.cc
libstdc++-v3/testsuite/27_io/ios_base/storage/11584.cc [new file with mode: 0644]

index ea093c2c9aa1f2fead1687157f31e0b886acd59f..65c10db3f2d4e19d98a731de99f4fe115af5473b 100644 (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>
 
index 587bda4b0928d0c884c3f09e655f01d08548bbdb..b937ac5c56718a19541b6a29897d7492f51e06ef 100644 (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;
     }
 
index 0dec32358c2fc0317233e95cea7cff3271eebfe6..6f987c22395fa705f7f197e5c11954790bc27f83 100644 (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;
          }
       }
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 (file)
index 0000000..8b1a7a7
--- /dev/null
@@ -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;
+}
+