]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
bitmap_allocator.h (allocate): Throw std::bad_alloc when n > max_size().
authorPaolo Carlini <pcarlini@suse.de>
Thu, 21 Oct 2004 00:06:02 +0000 (00:06 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Thu, 21 Oct 2004 00:06:02 +0000 (00:06 +0000)
2004-10-20  Paolo Carlini  <pcarlini@suse.de>

* include/ext/bitmap_allocator.h (allocate): Throw std::bad_alloc
when n > max_size().
* include/ext/malloc_allocator.h (allocate): Likewise.
* include/ext/mt_allocator.h (allocate): Likewise.
* include/ext/new_allocator.h (allocate): Likewise.
* include/ext/array_allocator.h: Use __throw_bad_alloc().
* include/ext/pool_allocator.h: Use __builtin_expect.
* testsuite/ext/array_allocator/check_allocate_max_size.cc: New.
* testsuite/ext/bitmap_allocator/check_allocate_max_size.cc: Likewise.
* testsuite/ext/malloc_allocator/check_allocate_max_size.cc: Likewise.
* testsuite/ext/mt_allocator/check_allocate_max_size.cc: Likewise.
* testsuite/ext/new_allocator/check_allocate_max_size.cc: Likewise.
* testsuite/ext/pool_allocator/check_allocate_max_size.cc: Likewise.
* testsuite/testsuite_allocator.h (check_allocate_max_size): New test.

From-SVN: r89351

14 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/include/ext/array_allocator.h
libstdc++-v3/include/ext/bitmap_allocator.h
libstdc++-v3/include/ext/malloc_allocator.h
libstdc++-v3/include/ext/mt_allocator.h
libstdc++-v3/include/ext/new_allocator.h
libstdc++-v3/include/ext/pool_allocator.h
libstdc++-v3/testsuite/ext/array_allocator/check_allocate_max_size.cc [new file with mode: 0644]
libstdc++-v3/testsuite/ext/bitmap_allocator/check_allocate_max_size.cc [new file with mode: 0644]
libstdc++-v3/testsuite/ext/malloc_allocator/check_allocate_max_size.cc [new file with mode: 0644]
libstdc++-v3/testsuite/ext/mt_allocator/check_allocate_max_size.cc [new file with mode: 0644]
libstdc++-v3/testsuite/ext/new_allocator/check_allocate_max_size.cc [new file with mode: 0644]
libstdc++-v3/testsuite/ext/pool_allocator/check_allocate_max_size.cc [new file with mode: 0644]
libstdc++-v3/testsuite/testsuite_allocator.h

index 8d6085328a0a1193ffa8aac60f1d499e0299c3a0..8e5934e109e66630f8e5bd1b68346724d683cc89 100644 (file)
@@ -1,3 +1,20 @@
+2004-10-20  Paolo Carlini  <pcarlini@suse.de>
+
+       * include/ext/bitmap_allocator.h (allocate): Throw std::bad_alloc
+       when n > max_size().
+       * include/ext/malloc_allocator.h (allocate): Likewise.
+       * include/ext/mt_allocator.h (allocate): Likewise.
+       * include/ext/new_allocator.h (allocate): Likewise.
+       * include/ext/array_allocator.h: Use __throw_bad_alloc().
+       * include/ext/pool_allocator.h: Use __builtin_expect.
+       * testsuite/ext/array_allocator/check_allocate_max_size.cc: New.
+       * testsuite/ext/bitmap_allocator/check_allocate_max_size.cc: Likewise.
+       * testsuite/ext/malloc_allocator/check_allocate_max_size.cc: Likewise.
+       * testsuite/ext/mt_allocator/check_allocate_max_size.cc: Likewise.
+       * testsuite/ext/new_allocator/check_allocate_max_size.cc: Likewise.
+       * testsuite/ext/pool_allocator/check_allocate_max_size.cc: Likewise.
+       * testsuite/testsuite_allocator.h (check_allocate_max_size): New test.
+
 2004-10-19  Paolo Carlini  <pcarlini@suse.de>
 
        * testsuite/performance/20_util/allocator/list_sort_search.cc:
index 585570a5722bd2e8f72eaa5429f5a510c04681d4..294ee68198f4abe0e70c3097bf718b96e9688989 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <cstddef>
 #include <new>
+#include <bits/functexcept.h>
 #include <tr1/array>
 
 namespace __gnu_cxx
@@ -118,7 +119,7 @@ namespace __gnu_cxx
       {
        static size_type __used;
        if (__builtin_expect(__used + __n > array_type::_S_index, false))
-         throw std::bad_alloc();
+         std::__throw_bad_alloc();
        pointer __ret = _M_array->begin() + __used;
        __used += __n;
        return __ret;
index 793f4dc81f73d97d614723a7b92293bfbbdaccf3..dc24465612399b41f83a8670ad53ac9b5cbed16a 100644 (file)
@@ -38,6 +38,9 @@
 // For std::size_t, and ptrdiff_t.
 #include <cstddef>
 
+// For __throw_bad_alloc().
+#include <bits/functexcept.h>
+
 // For std::pair.
 #include <utility>
 
@@ -1084,6 +1087,9 @@ namespace __gnu_cxx
       pointer 
       allocate(size_type __n)
       {
+       if (__builtin_expect(__n > this->max_size(), false))
+         std::__throw_bad_alloc();
+
        if (__builtin_expect(__n == 1, true))
          return this->_M_allocate_single_object();
        else
@@ -1119,7 +1125,7 @@ namespace __gnu_cxx
 
       size_type 
       max_size() const throw()
-      { return (size_type()-1)/sizeof(value_type); }
+      { return size_type(-1) / sizeof(value_type); }
 
       void 
       construct(pointer __p, const_reference __data)
index 938380c36f6e4524788e50525e9b3f58fed64193..ba4d2d756012afe954a6efa3fda9eaeb543586e0 100644 (file)
@@ -31,6 +31,7 @@
 #define _MALLOC_ALLOCATOR_H 1
 
 #include <new>
+#include <bits/functexcept.h>
 
 namespace __gnu_cxx
 {
@@ -79,9 +80,12 @@ namespace __gnu_cxx
       pointer
       allocate(size_type __n, const void* = 0)
       {
+       if (__builtin_expect(__n > this->max_size(), false))
+         std::__throw_bad_alloc();
+
        pointer __ret = static_cast<_Tp*>(malloc(__n * sizeof(_Tp)));
        if (!__ret)
-         throw std::bad_alloc();
+         std::__throw_bad_alloc();
        return __ret;
       }
 
index 5e587ad43da5a1ce52553e5e5add386f22927c73..6649111a6e7d3f11b5f42a88bb908639eb3db036 100644 (file)
@@ -685,6 +685,9 @@ namespace __gnu_cxx
     {
       this->_S_initialize_once();
 
+      if (__builtin_expect(__n > this->max_size(), false))
+       std::__throw_bad_alloc();
+
       // Requests larger than _M_max_bytes are handled by operator
       // new/delete directly.
       __pool_type& __pool = this->_S_get_pool();
@@ -694,7 +697,7 @@ namespace __gnu_cxx
          void* __ret = ::operator new(__bytes);
          return static_cast<_Tp*>(__ret);
        }
-
+      
       // Round up to power of 2 and figure out which bin to use.
       const size_t __which = __pool._M_get_binmap(__bytes);
       const size_t __thread_id = __pool._M_get_thread_id();
index 1b0b4f6107962cb5c82c296f8a9b28b0267e57af..145f98b476a7cc5f429781057db6e04a69e914bc 100644 (file)
@@ -31,6 +31,7 @@
 #define _NEW_ALLOCATOR_H 1
 
 #include <new>
+#include <bits/functexcept.h>
 
 namespace __gnu_cxx
 {
@@ -78,7 +79,12 @@ namespace __gnu_cxx
       // about what the return value is when __n == 0.
       pointer
       allocate(size_type __n, const void* = 0)
-      { return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); }
+      { 
+       if (__builtin_expect(__n > this->max_size(), false))
+         std::__throw_bad_alloc();
+
+       return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
+      }
 
       // __p is not permitted to be a null pointer.
       void
index 0b95906ccfd1b93a4bc78d2d21ca5735b5b81b1d..d2110f78ad3904f392cc6ce105b143f6b222dbc9 100644 (file)
@@ -189,43 +189,41 @@ namespace __gnu_cxx
     __pool_alloc<_Tp>::allocate(size_type __n, const void*)
     {
       pointer __ret = 0;
-      if (__n)
+      if (__builtin_expect(__n != 0, true))
        {
-         if (__n <= max_size())
+         if (__builtin_expect(__n > this->max_size(), false))
+           std::__throw_bad_alloc();
+
+         // If there is a race through here, assume answer from getenv
+         // will resolve in same direction.  Inspired by techniques
+         // to efficiently support threading found in basic_string.h.
+         if (_S_force_new == 0)
            {
-             // If there is a race through here, assume answer from getenv
-             // will resolve in same direction.  Inspired by techniques
-             // to efficiently support threading found in basic_string.h.
-             if (_S_force_new == 0)
-               {
-                 if (getenv("GLIBCXX_FORCE_NEW"))
-                   __atomic_add(&_S_force_new, 1);
-                 else
-                   __atomic_add(&_S_force_new, -1);
-               }
+             if (getenv("GLIBCXX_FORCE_NEW"))
+               __atomic_add(&_S_force_new, 1);
+             else
+               __atomic_add(&_S_force_new, -1);
+           }
 
-             const size_t __bytes = __n * sizeof(_Tp);       
-             if (__bytes > size_t(_S_max_bytes) || _S_force_new == 1)
-               __ret = static_cast<_Tp*>(::operator new(__bytes));
+         const size_t __bytes = __n * sizeof(_Tp);           
+         if (__bytes > size_t(_S_max_bytes) || _S_force_new == 1)
+           __ret = static_cast<_Tp*>(::operator new(__bytes));
+         else
+           {
+             _Obj* volatile* __free_list = _M_get_free_list(__bytes);
+             
+             lock sentry(_M_get_mutex());
+             _Obj* __restrict__ __result = *__free_list;
+             if (__builtin_expect(__result == 0, 0))
+               __ret = static_cast<_Tp*>(_M_refill(_M_round_up(__bytes)));
              else
                {
-                 _Obj* volatile* __free_list = _M_get_free_list(__bytes);
-
-                 lock sentry(_M_get_mutex());
-                 _Obj* __restrict__ __result = *__free_list;
-                 if (__builtin_expect(__result == 0, 0))
-                   __ret = static_cast<_Tp*>(_M_refill(_M_round_up(__bytes)));
-                 else
-                   {
-                     *__free_list = __result->_M_free_list_link;
-                     __ret = reinterpret_cast<_Tp*>(__result);
-                   }
-                 if (__builtin_expect(__ret == 0, 0))
-                   std::__throw_bad_alloc();
+                 *__free_list = __result->_M_free_list_link;
+                 __ret = reinterpret_cast<_Tp*>(__result);
                }
+             if (__builtin_expect(__ret == 0, 0))
+               std::__throw_bad_alloc();
            }
-         else
-           std::__throw_bad_alloc();
        }
       return __ret;
     }
@@ -234,7 +232,7 @@ namespace __gnu_cxx
     void
     __pool_alloc<_Tp>::deallocate(pointer __p, size_type __n)
     {
-      if (__n && (__p != 0))
+      if (__builtin_expect(__n != 0 && __p != 0, true))
        {
          const size_t __bytes = __n * sizeof(_Tp);
          if (__bytes > static_cast<size_t>(_S_max_bytes) || _S_force_new == 1)
diff --git a/libstdc++-v3/testsuite/ext/array_allocator/check_allocate_max_size.cc b/libstdc++-v3/testsuite/ext/array_allocator/check_allocate_max_size.cc
new file mode 100644 (file)
index 0000000..4225ee2
--- /dev/null
@@ -0,0 +1,31 @@
+//
+// Copyright (C) 2004 Free Software Foundation, Inc.
+//
+// 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.
+
+// 20.4.1.1 allocator members
+
+#include <ext/array_allocator.h>
+#include <testsuite_allocator.h>
+
+int main()
+{ 
+  typedef int value_type;
+  typedef __gnu_cxx::array_allocator<value_type> allocator_type;
+  __gnu_test::check_allocate_max_size<allocator_type>();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/bitmap_allocator/check_allocate_max_size.cc b/libstdc++-v3/testsuite/ext/bitmap_allocator/check_allocate_max_size.cc
new file mode 100644 (file)
index 0000000..442b91d
--- /dev/null
@@ -0,0 +1,31 @@
+//
+// Copyright (C) 2004 Free Software Foundation, Inc.
+//
+// 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.
+
+// 20.4.1.1 allocator members
+
+#include <ext/bitmap_allocator.h>
+#include <testsuite_allocator.h>
+
+int main()
+{ 
+  typedef int value_type;
+  typedef __gnu_cxx::bitmap_allocator<value_type> allocator_type;
+  __gnu_test::check_allocate_max_size<allocator_type>();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/malloc_allocator/check_allocate_max_size.cc b/libstdc++-v3/testsuite/ext/malloc_allocator/check_allocate_max_size.cc
new file mode 100644 (file)
index 0000000..421eb7b
--- /dev/null
@@ -0,0 +1,31 @@
+//
+// Copyright (C) 2004 Free Software Foundation, Inc.
+//
+// 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.
+
+// 20.4.1.1 allocator members
+
+#include <ext/malloc_allocator.h>
+#include <testsuite_allocator.h>
+
+int main()
+{
+  typedef int value_type;
+  typedef __gnu_cxx::malloc_allocator<value_type> allocator_type;
+  __gnu_test::check_allocate_max_size<allocator_type>();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/check_allocate_max_size.cc b/libstdc++-v3/testsuite/ext/mt_allocator/check_allocate_max_size.cc
new file mode 100644 (file)
index 0000000..1beaf93
--- /dev/null
@@ -0,0 +1,31 @@
+//
+// Copyright (C) 2004 Free Software Foundation, Inc.
+//
+// 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.
+
+// 20.4.1.1 allocator members
+
+#include <ext/mt_allocator.h>
+#include <testsuite_allocator.h>
+
+int main()
+{ 
+  typedef int value_type;
+  typedef __gnu_cxx::__mt_alloc<value_type> allocator_type;
+  __gnu_test::check_allocate_max_size<allocator_type>();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/new_allocator/check_allocate_max_size.cc b/libstdc++-v3/testsuite/ext/new_allocator/check_allocate_max_size.cc
new file mode 100644 (file)
index 0000000..d5e0132
--- /dev/null
@@ -0,0 +1,31 @@
+//
+// Copyright (C) 2004 Free Software Foundation, Inc.
+//
+// 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.
+
+// 20.4.1.1 allocator members
+
+#include <ext/new_allocator.h>
+#include <testsuite_allocator.h>
+
+int main()
+{ 
+  typedef int value_type;
+  typedef __gnu_cxx::new_allocator<value_type> allocator_type;
+  __gnu_test::check_allocate_max_size<allocator_type>();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/pool_allocator/check_allocate_max_size.cc b/libstdc++-v3/testsuite/ext/pool_allocator/check_allocate_max_size.cc
new file mode 100644 (file)
index 0000000..9c96c3d
--- /dev/null
@@ -0,0 +1,31 @@
+//
+// Copyright (C) 2004 Free Software Foundation, Inc.
+//
+// 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.
+
+// 20.4.1.1 allocator members
+
+#include <ext/pool_allocator.h>
+#include <testsuite_allocator.h>
+
+int main()
+{ 
+  typedef int value_type;
+  typedef __gnu_cxx::__pool_alloc<value_type> allocator_type;
+  __gnu_test::check_allocate_max_size<allocator_type>();
+  return 0;
+}
index c10be5315d9da02404eea2277b9587fc9fa3ce07..7c353445e8a7baa70f31482ab4598aa9fab09d12 100644 (file)
@@ -36,6 +36,7 @@
 #define _GLIBCXX_TESTSUITE_ALLOCATOR_H
 
 #include <cstddef>
+#include <cstdlib>
 #include <limits>
 
 namespace 
@@ -205,7 +206,27 @@ namespace __gnu_test
       a.deallocate(NULL, 1);
       a.deallocate(NULL, 10);
     }
+
+  template<typename Alloc>
+    bool 
+    check_allocate_max_size()
+    {
+      Alloc a;
+      try
+       {
+         a.allocate(a.max_size() + 1);
+       }
+      catch(std::bad_alloc&)
+       {
+         return true;
+       }
+      catch(...)
+       {
+         throw;
+       }
+      throw;
+    }
+
 }; // namespace __gnu_test
 
 #endif // _GLIBCXX_TESTSUITE_ALLOCATOR_H
-