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/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 ++++++++++++++--------------- 6 files changed, 54 insertions(+), 36 deletions(-) (limited to 'libstdc++-v3/include/ext') 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) -- cgit v1.1