From a063e891bd88967d9dcea0f8c163f8372116265f Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Thu, 21 Oct 2004 00:06:02 +0000 Subject: bitmap_allocator.h (allocate): Throw std::bad_alloc when n > max_size(). 2004-10-20 Paolo Carlini * 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 --- libstdc++-v3/ChangeLog | 17 ++++++ libstdc++-v3/include/ext/array_allocator.h | 3 +- libstdc++-v3/include/ext/bitmap_allocator.h | 8 ++- libstdc++-v3/include/ext/malloc_allocator.h | 6 ++- libstdc++-v3/include/ext/mt_allocator.h | 5 +- libstdc++-v3/include/ext/new_allocator.h | 8 ++- libstdc++-v3/include/ext/pool_allocator.h | 60 +++++++++++----------- .../ext/array_allocator/check_allocate_max_size.cc | 31 +++++++++++ .../bitmap_allocator/check_allocate_max_size.cc | 31 +++++++++++ .../malloc_allocator/check_allocate_max_size.cc | 31 +++++++++++ .../ext/mt_allocator/check_allocate_max_size.cc | 31 +++++++++++ .../ext/new_allocator/check_allocate_max_size.cc | 31 +++++++++++ .../ext/pool_allocator/check_allocate_max_size.cc | 31 +++++++++++ libstdc++-v3/testsuite/testsuite_allocator.h | 23 ++++++++- 14 files changed, 279 insertions(+), 37 deletions(-) create mode 100644 libstdc++-v3/testsuite/ext/array_allocator/check_allocate_max_size.cc create mode 100644 libstdc++-v3/testsuite/ext/bitmap_allocator/check_allocate_max_size.cc create mode 100644 libstdc++-v3/testsuite/ext/malloc_allocator/check_allocate_max_size.cc create mode 100644 libstdc++-v3/testsuite/ext/mt_allocator/check_allocate_max_size.cc create mode 100644 libstdc++-v3/testsuite/ext/new_allocator/check_allocate_max_size.cc create mode 100644 libstdc++-v3/testsuite/ext/pool_allocator/check_allocate_max_size.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 8d60853..8e5934e 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,20 @@ +2004-10-20 Paolo Carlini + + * 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 * testsuite/performance/20_util/allocator/list_sort_search.cc: diff --git a/libstdc++-v3/include/ext/array_allocator.h b/libstdc++-v3/include/ext/array_allocator.h index 585570a..294ee68 100644 --- a/libstdc++-v3/include/ext/array_allocator.h +++ b/libstdc++-v3/include/ext/array_allocator.h @@ -32,6 +32,7 @@ #include #include +#include #include 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; diff --git a/libstdc++-v3/include/ext/bitmap_allocator.h b/libstdc++-v3/include/ext/bitmap_allocator.h index 793f4dc..dc24465 100644 --- a/libstdc++-v3/include/ext/bitmap_allocator.h +++ b/libstdc++-v3/include/ext/bitmap_allocator.h @@ -38,6 +38,9 @@ // For std::size_t, and ptrdiff_t. #include +// For __throw_bad_alloc(). +#include + // For std::pair. #include @@ -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) diff --git a/libstdc++-v3/include/ext/malloc_allocator.h b/libstdc++-v3/include/ext/malloc_allocator.h index 938380c..ba4d2d7 100644 --- a/libstdc++-v3/include/ext/malloc_allocator.h +++ b/libstdc++-v3/include/ext/malloc_allocator.h @@ -31,6 +31,7 @@ #define _MALLOC_ALLOCATOR_H 1 #include +#include 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; } diff --git a/libstdc++-v3/include/ext/mt_allocator.h b/libstdc++-v3/include/ext/mt_allocator.h index 5e587ad..6649111 100644 --- a/libstdc++-v3/include/ext/mt_allocator.h +++ b/libstdc++-v3/include/ext/mt_allocator.h @@ -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(); diff --git a/libstdc++-v3/include/ext/new_allocator.h b/libstdc++-v3/include/ext/new_allocator.h index 1b0b4f6..145f98b 100644 --- a/libstdc++-v3/include/ext/new_allocator.h +++ b/libstdc++-v3/include/ext/new_allocator.h @@ -31,6 +31,7 @@ #define _NEW_ALLOCATOR_H 1 #include +#include 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 diff --git a/libstdc++-v3/include/ext/pool_allocator.h b/libstdc++-v3/include/ext/pool_allocator.h index 0b95906..d2110f7 100644 --- a/libstdc++-v3/include/ext/pool_allocator.h +++ b/libstdc++-v3/include/ext/pool_allocator.h @@ -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(_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 index 0000000..4225ee2 --- /dev/null +++ b/libstdc++-v3/testsuite/ext/array_allocator/check_allocate_max_size.cc @@ -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 +#include + +int main() +{ + typedef int value_type; + typedef __gnu_cxx::array_allocator allocator_type; + __gnu_test::check_allocate_max_size(); + 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 index 0000000..442b91d --- /dev/null +++ b/libstdc++-v3/testsuite/ext/bitmap_allocator/check_allocate_max_size.cc @@ -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 +#include + +int main() +{ + typedef int value_type; + typedef __gnu_cxx::bitmap_allocator allocator_type; + __gnu_test::check_allocate_max_size(); + 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 index 0000000..421eb7b --- /dev/null +++ b/libstdc++-v3/testsuite/ext/malloc_allocator/check_allocate_max_size.cc @@ -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 +#include + +int main() +{ + typedef int value_type; + typedef __gnu_cxx::malloc_allocator allocator_type; + __gnu_test::check_allocate_max_size(); + 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 index 0000000..1beaf93 --- /dev/null +++ b/libstdc++-v3/testsuite/ext/mt_allocator/check_allocate_max_size.cc @@ -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 +#include + +int main() +{ + typedef int value_type; + typedef __gnu_cxx::__mt_alloc allocator_type; + __gnu_test::check_allocate_max_size(); + 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 index 0000000..d5e0132 --- /dev/null +++ b/libstdc++-v3/testsuite/ext/new_allocator/check_allocate_max_size.cc @@ -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 +#include + +int main() +{ + typedef int value_type; + typedef __gnu_cxx::new_allocator allocator_type; + __gnu_test::check_allocate_max_size(); + 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 index 0000000..9c96c3d --- /dev/null +++ b/libstdc++-v3/testsuite/ext/pool_allocator/check_allocate_max_size.cc @@ -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 +#include + +int main() +{ + typedef int value_type; + typedef __gnu_cxx::__pool_alloc allocator_type; + __gnu_test::check_allocate_max_size(); + return 0; +} diff --git a/libstdc++-v3/testsuite/testsuite_allocator.h b/libstdc++-v3/testsuite/testsuite_allocator.h index c10be53..7c35344 100644 --- a/libstdc++-v3/testsuite/testsuite_allocator.h +++ b/libstdc++-v3/testsuite/testsuite_allocator.h @@ -36,6 +36,7 @@ #define _GLIBCXX_TESTSUITE_ALLOCATOR_H #include +#include #include namespace @@ -205,7 +206,27 @@ namespace __gnu_test a.deallocate(NULL, 1); a.deallocate(NULL, 10); } + + template + 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 - -- cgit v1.1