This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[v3] Add max_size() checks to the allocators


Hi,

various versions tested on x86/x86_64/ia64, --enable-libstdcxx-allocator=mt,
bitmap, pool, new.

Committed to mainline.

Paolo.

///////////////

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.
diff -urN libstdc++-v3-orig/include/ext/array_allocator.h libstdc++-v3/include/ext/array_allocator.h
--- libstdc++-v3-orig/include/ext/array_allocator.h	2004-10-15 01:03:23.000000000 +0200
+++ libstdc++-v3/include/ext/array_allocator.h	2004-10-20 18:28:18.000000000 +0200
@@ -32,6 +32,7 @@
 
 #include <cstddef>
 #include <new>
+#include <bits/functexcept.h>
 #include <tr1/array>
 
 namespace __gnu_cxx
@@ -118,7 +119,7 @@
       {
 	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;
diff -urN libstdc++-v3-orig/include/ext/bitmap_allocator.h libstdc++-v3/include/ext/bitmap_allocator.h
--- libstdc++-v3-orig/include/ext/bitmap_allocator.h	2004-10-17 16:46:29.000000000 +0200
+++ libstdc++-v3/include/ext/bitmap_allocator.h	2004-10-20 18:58:19.000000000 +0200
@@ -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 @@
       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 @@
 
       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)
diff -urN libstdc++-v3-orig/include/ext/malloc_allocator.h libstdc++-v3/include/ext/malloc_allocator.h
--- libstdc++-v3-orig/include/ext/malloc_allocator.h	2004-03-24 22:40:01.000000000 +0100
+++ libstdc++-v3/include/ext/malloc_allocator.h	2004-10-20 18:54:46.000000000 +0200
@@ -31,6 +31,7 @@
 #define _MALLOC_ALLOCATOR_H 1
 
 #include <new>
+#include <bits/functexcept.h>
 
 namespace __gnu_cxx
 {
@@ -79,9 +80,12 @@
       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;
       }
 
diff -urN libstdc++-v3-orig/include/ext/mt_allocator.h libstdc++-v3/include/ext/mt_allocator.h
--- libstdc++-v3-orig/include/ext/mt_allocator.h	2004-10-17 17:22:02.000000000 +0200
+++ libstdc++-v3/include/ext/mt_allocator.h	2004-10-20 18:46:09.000000000 +0200
@@ -685,6 +685,9 @@
     {
       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 @@
 	  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();
diff -urN libstdc++-v3-orig/include/ext/new_allocator.h libstdc++-v3/include/ext/new_allocator.h
--- libstdc++-v3-orig/include/ext/new_allocator.h	2004-02-23 16:41:43.000000000 +0100
+++ libstdc++-v3/include/ext/new_allocator.h	2004-10-20 18:55:47.000000000 +0200
@@ -31,6 +31,7 @@
 #define _NEW_ALLOCATOR_H 1
 
 #include <new>
+#include <bits/functexcept.h>
 
 namespace __gnu_cxx
 {
@@ -78,7 +79,12 @@
       // 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
diff -urN libstdc++-v3-orig/include/ext/pool_allocator.h libstdc++-v3/include/ext/pool_allocator.h
--- libstdc++-v3-orig/include/ext/pool_allocator.h	2004-10-15 01:03:24.000000000 +0200
+++ libstdc++-v3/include/ext/pool_allocator.h	2004-10-20 18:49:59.000000000 +0200
@@ -189,43 +189,41 @@
     __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 @@
     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 -urN libstdc++-v3-orig/testsuite/ext/array_allocator/check_allocate_max_size.cc libstdc++-v3/testsuite/ext/array_allocator/check_allocate_max_size.cc
--- libstdc++-v3-orig/testsuite/ext/array_allocator/check_allocate_max_size.cc	1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/testsuite/ext/array_allocator/check_allocate_max_size.cc	2004-10-21 01:09:04.000000000 +0200
@@ -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 -urN libstdc++-v3-orig/testsuite/ext/bitmap_allocator/check_allocate_max_size.cc libstdc++-v3/testsuite/ext/bitmap_allocator/check_allocate_max_size.cc
--- libstdc++-v3-orig/testsuite/ext/bitmap_allocator/check_allocate_max_size.cc	1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/testsuite/ext/bitmap_allocator/check_allocate_max_size.cc	2004-10-21 01:09:19.000000000 +0200
@@ -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 -urN libstdc++-v3-orig/testsuite/ext/malloc_allocator/check_allocate_max_size.cc libstdc++-v3/testsuite/ext/malloc_allocator/check_allocate_max_size.cc
--- libstdc++-v3-orig/testsuite/ext/malloc_allocator/check_allocate_max_size.cc	1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/testsuite/ext/malloc_allocator/check_allocate_max_size.cc	2004-10-21 01:09:34.000000000 +0200
@@ -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 -urN libstdc++-v3-orig/testsuite/ext/mt_allocator/check_allocate_max_size.cc libstdc++-v3/testsuite/ext/mt_allocator/check_allocate_max_size.cc
--- libstdc++-v3-orig/testsuite/ext/mt_allocator/check_allocate_max_size.cc	1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/testsuite/ext/mt_allocator/check_allocate_max_size.cc	2004-10-21 01:09:51.000000000 +0200
@@ -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 -urN libstdc++-v3-orig/testsuite/ext/new_allocator/check_allocate_max_size.cc libstdc++-v3/testsuite/ext/new_allocator/check_allocate_max_size.cc
--- libstdc++-v3-orig/testsuite/ext/new_allocator/check_allocate_max_size.cc	1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/testsuite/ext/new_allocator/check_allocate_max_size.cc	2004-10-21 01:10:05.000000000 +0200
@@ -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 -urN libstdc++-v3-orig/testsuite/ext/pool_allocator/check_allocate_max_size.cc libstdc++-v3/testsuite/ext/pool_allocator/check_allocate_max_size.cc
--- libstdc++-v3-orig/testsuite/ext/pool_allocator/check_allocate_max_size.cc	1970-01-01 01:00:00.000000000 +0100
+++ libstdc++-v3/testsuite/ext/pool_allocator/check_allocate_max_size.cc	2004-10-21 01:10:19.000000000 +0200
@@ -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;
+}
diff -urN libstdc++-v3-orig/testsuite/testsuite_allocator.h libstdc++-v3/testsuite/testsuite_allocator.h
--- libstdc++-v3-orig/testsuite/testsuite_allocator.h	2004-10-15 12:54:57.000000000 +0200
+++ libstdc++-v3/testsuite/testsuite_allocator.h	2004-10-20 18:17:29.000000000 +0200
@@ -36,6 +36,7 @@
 #define _GLIBCXX_TESTSUITE_ALLOCATOR_H
 
 #include <cstddef>
+#include <cstdlib>
 #include <limits>
 
 namespace 
@@ -205,7 +206,27 @@
       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
-

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]