From 5d1b2a1e421e770aba056e6b1405ed0eb29d29eb Mon Sep 17 00:00:00 2001 From: Benjamin Kosnik Date: Thu, 14 Oct 2004 23:03:26 +0000 Subject: [PATCH] mt_allocator.h (__mt_alloc::deallocate): Check for null pointer. 2004-10-14 Benjamin Kosnik * include/ext/mt_allocator.h (__mt_alloc::deallocate): Check for null pointer. * include/ext/pool_allocator.h (debug_allocator::deallocate): Check pointer value. * include/ext/debug_allocator.h (debug_allocator::deallocate): Throw exceptions, don't abort. * include/ext/array_allocator.h (array_allocator_base::deallocate): Remove unused parameters. * testsuite/testsuite_allocator.h (check_deallocate_null): New. * testsuite/ext/mt_allocator/check_deallocate_null.cc: New. * testsuite/ext/mt_allocator/check_deallocate_null_thread.cc: New. * testsuite/ext/array_allocator/check_deallocate_null.cc: New. * testsuite/ext/debug_allocator/check_deallocate_null.cc: New. * testsuite/ext/malloc_allocator/check_deallocate_null.cc: New. * testsuite/ext/new_allocator/check_deallocate_null.cc: New. * testsuite/ext/pool_allocator/check_deallocate_null.cc: New. * testsuite/testsuite_allocator.h (check_new): Add instance argument. * testsuite/ext/array_allocator/check_new.cc: New. From-SVN: r89060 --- libstdc++-v3/ChangeLog | 22 +++++++ libstdc++-v3/include/ext/array_allocator.h | 2 +- libstdc++-v3/include/ext/debug_allocator.h | 20 ++++--- libstdc++-v3/include/ext/mt_allocator.h | 19 +++--- libstdc++-v3/include/ext/pool_allocator.h | 2 +- .../array_allocator/check_deallocate_null.cc | 32 ++++++++++ .../ext/array_allocator/check_new.cc | 59 +++++++++++++++++++ .../debug_allocator/check_deallocate_null.cc | 48 +++++++++++++++ .../malloc_allocator/check_deallocate_null.cc | 32 ++++++++++ .../ext/mt_allocator/check_deallocate_null.cc | 33 +++++++++++ .../check_deallocate_null_thread.cc | 33 +++++++++++ .../new_allocator/check_deallocate_null.cc | 32 ++++++++++ .../pool_allocator/check_deallocate_null.cc | 32 ++++++++++ libstdc++-v3/testsuite/testsuite_allocator.h | 37 +++++++----- 14 files changed, 372 insertions(+), 31 deletions(-) create mode 100644 libstdc++-v3/testsuite/ext/array_allocator/check_deallocate_null.cc create mode 100644 libstdc++-v3/testsuite/ext/array_allocator/check_new.cc create mode 100644 libstdc++-v3/testsuite/ext/debug_allocator/check_deallocate_null.cc create mode 100644 libstdc++-v3/testsuite/ext/malloc_allocator/check_deallocate_null.cc create mode 100644 libstdc++-v3/testsuite/ext/mt_allocator/check_deallocate_null.cc create mode 100644 libstdc++-v3/testsuite/ext/mt_allocator/check_deallocate_null_thread.cc create mode 100644 libstdc++-v3/testsuite/ext/new_allocator/check_deallocate_null.cc create mode 100644 libstdc++-v3/testsuite/ext/pool_allocator/check_deallocate_null.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index d8652be25cb..d5bdab551b0 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,25 @@ +2004-10-14 Benjamin Kosnik + + * include/ext/mt_allocator.h (__mt_alloc::deallocate): Check for + null pointer. + * include/ext/pool_allocator.h (debug_allocator::deallocate): + Check pointer value. + * include/ext/debug_allocator.h (debug_allocator::deallocate): + Throw exceptions, don't abort. + * include/ext/array_allocator.h + (array_allocator_base::deallocate): Remove unused parameters. + * testsuite/testsuite_allocator.h (check_deallocate_null): New. + * testsuite/ext/mt_allocator/check_deallocate_null.cc: New. + * testsuite/ext/mt_allocator/check_deallocate_null_thread.cc: New. + * testsuite/ext/array_allocator/check_deallocate_null.cc: New. + * testsuite/ext/debug_allocator/check_deallocate_null.cc: New. + * testsuite/ext/malloc_allocator/check_deallocate_null.cc: New. + * testsuite/ext/new_allocator/check_deallocate_null.cc: New. + * testsuite/ext/pool_allocator/check_deallocate_null.cc: New. + + * testsuite/testsuite_allocator.h (check_new): Add instance argument. + * testsuite/ext/array_allocator/check_new.cc: New. + 2004-10-14 Paolo Carlini * include/ext/bitmap_allocator.h (bitmap_allocator::_Alloc_block): diff --git a/libstdc++-v3/include/ext/array_allocator.h b/libstdc++-v3/include/ext/array_allocator.h index 66aa903e154..585570a5722 100644 --- a/libstdc++-v3/include/ext/array_allocator.h +++ b/libstdc++-v3/include/ext/array_allocator.h @@ -55,7 +55,7 @@ namespace __gnu_cxx address(const_reference __x) const { return &__x; } void - deallocate(pointer __p, size_type) + deallocate(pointer, size_type) { // Does nothing. } diff --git a/libstdc++-v3/include/ext/debug_allocator.h b/libstdc++-v3/include/ext/debug_allocator.h index 7ea6fb42f98..7fff5d389d8 100644 --- a/libstdc++-v3/include/ext/debug_allocator.h +++ b/libstdc++-v3/include/ext/debug_allocator.h @@ -48,7 +48,7 @@ #ifndef _DEBUG_ALLOCATOR_H #define _DEBUG_ALLOCATOR_H 1 -#include +#include namespace __gnu_cxx { @@ -108,12 +108,18 @@ namespace __gnu_cxx void deallocate(pointer __p, size_type __n) { - if (!__p) - abort(); - pointer __real_p = __p - _M_extra; - if (*reinterpret_cast(__real_p) != __n) - abort(); - _M_allocator.deallocate(__real_p, __n + _M_extra); + if (__p) + { + pointer __real_p = __p - _M_extra; + if (*reinterpret_cast(__real_p) != __n) + { + throw std::runtime_error("debug_allocator::deallocate" + " wrong size"); + } + _M_allocator.deallocate(__real_p, __n + _M_extra); + } + else + throw std::runtime_error("debug_allocator::deallocate null pointer"); } }; } // namespace __gnu_cxx diff --git a/libstdc++-v3/include/ext/mt_allocator.h b/libstdc++-v3/include/ext/mt_allocator.h index 3bbfc79b4bb..d4d51d8a55e 100644 --- a/libstdc++-v3/include/ext/mt_allocator.h +++ b/libstdc++-v3/include/ext/mt_allocator.h @@ -724,14 +724,17 @@ namespace __gnu_cxx __mt_alloc<_Tp, _Poolp>:: deallocate(pointer __p, size_type __n) { - // Requests larger than _M_max_bytes are handled by operators - // new/delete directly. - __pool_type& __pool = this->_S_get_pool(); - const size_t __bytes = __n * sizeof(_Tp); - if (__pool._M_check_threshold(__bytes)) - ::operator delete(__p); - else - __pool._M_reclaim_block(reinterpret_cast(__p), __bytes); + if (__builtin_expect(__p != 0, true)) + { + // Requests larger than _M_max_bytes are handled by + // operators new/delete directly. + __pool_type& __pool = this->_S_get_pool(); + const size_t __bytes = __n * sizeof(_Tp); + if (__pool._M_check_threshold(__bytes)) + ::operator delete(__p); + else + __pool._M_reclaim_block(reinterpret_cast(__p), __bytes); + } } template diff --git a/libstdc++-v3/include/ext/pool_allocator.h b/libstdc++-v3/include/ext/pool_allocator.h index 0f087a03c1e..0b95906ccfd 100644 --- a/libstdc++-v3/include/ext/pool_allocator.h +++ b/libstdc++-v3/include/ext/pool_allocator.h @@ -234,7 +234,7 @@ namespace __gnu_cxx void __pool_alloc<_Tp>::deallocate(pointer __p, size_type __n) { - if (__n) + if (__n && (__p != 0)) { 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_deallocate_null.cc b/libstdc++-v3/testsuite/ext/array_allocator/check_deallocate_null.cc new file mode 100644 index 00000000000..9d743a19178 --- /dev/null +++ b/libstdc++-v3/testsuite/ext/array_allocator/check_deallocate_null.cc @@ -0,0 +1,32 @@ +// +// 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_deallocate_null(); + return 0; +} + diff --git a/libstdc++-v3/testsuite/ext/array_allocator/check_new.cc b/libstdc++-v3/testsuite/ext/array_allocator/check_new.cc new file mode 100644 index 00000000000..2d15972f6a7 --- /dev/null +++ b/libstdc++-v3/testsuite/ext/array_allocator/check_new.cc @@ -0,0 +1,59 @@ +// 2001-11-25 Phil Edwards +// +// Copyright (C) 2001, 2003, 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 +#include + +using __gnu_cxx::array_allocator; + +void* +operator new(std::size_t n) throw(std::bad_alloc) +{ + new_called = true; + requested = n; + return std::malloc(n); +} + +void +operator delete(void *v) throw() +{ + delete_called = true; + return std::free(v); +} + +// These just help tracking down error messages. +bool test01() +{ + typedef unsigned int value_type; + typedef std::tr1::array array_type; + typedef array_allocator allocator_type; + array_type store; + allocator_type a(&store); + return (__gnu_test::check_new(a) == false); +} + +int main() +{ + return test01(); +} + diff --git a/libstdc++-v3/testsuite/ext/debug_allocator/check_deallocate_null.cc b/libstdc++-v3/testsuite/ext/debug_allocator/check_deallocate_null.cc new file mode 100644 index 00000000000..dd9d28114d5 --- /dev/null +++ b/libstdc++-v3/testsuite/ext/debug_allocator/check_deallocate_null.cc @@ -0,0 +1,48 @@ +// +// 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 +#include +#include + +int main() +{ + typedef int value_type; + typedef std::allocator debug_type; + typedef __gnu_cxx::debug_allocator allocator_type; + + try + { + __gnu_test::check_deallocate_null(); + } + catch (std::runtime_error& obj) + { + // Ok. + } + catch (...) + { + // Shouldn't get here. + throw; + } + return 0; +} + diff --git a/libstdc++-v3/testsuite/ext/malloc_allocator/check_deallocate_null.cc b/libstdc++-v3/testsuite/ext/malloc_allocator/check_deallocate_null.cc new file mode 100644 index 00000000000..bdea99b5ad7 --- /dev/null +++ b/libstdc++-v3/testsuite/ext/malloc_allocator/check_deallocate_null.cc @@ -0,0 +1,32 @@ +// +// 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_deallocate_null(); + return 0; +} + diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/check_deallocate_null.cc b/libstdc++-v3/testsuite/ext/mt_allocator/check_deallocate_null.cc new file mode 100644 index 00000000000..d9cdb0f7b52 --- /dev/null +++ b/libstdc++-v3/testsuite/ext/mt_allocator/check_deallocate_null.cc @@ -0,0 +1,33 @@ +// +// 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::__common_pool_policy policy_type; + typedef __gnu_cxx::__mt_alloc allocator_type; + __gnu_test::check_deallocate_null(); + return 0; +} + diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/check_deallocate_null_thread.cc b/libstdc++-v3/testsuite/ext/mt_allocator/check_deallocate_null_thread.cc new file mode 100644 index 00000000000..28aed3b3ea0 --- /dev/null +++ b/libstdc++-v3/testsuite/ext/mt_allocator/check_deallocate_null_thread.cc @@ -0,0 +1,33 @@ +// +// 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::__common_pool_policy policy_type; + typedef __gnu_cxx::__mt_alloc allocator_type; + __gnu_test::check_deallocate_null(); + return 0; +} + diff --git a/libstdc++-v3/testsuite/ext/new_allocator/check_deallocate_null.cc b/libstdc++-v3/testsuite/ext/new_allocator/check_deallocate_null.cc new file mode 100644 index 00000000000..34ed42c147b --- /dev/null +++ b/libstdc++-v3/testsuite/ext/new_allocator/check_deallocate_null.cc @@ -0,0 +1,32 @@ +// +// 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_deallocate_null(); + return 0; +} + diff --git a/libstdc++-v3/testsuite/ext/pool_allocator/check_deallocate_null.cc b/libstdc++-v3/testsuite/ext/pool_allocator/check_deallocate_null.cc new file mode 100644 index 00000000000..4b4999eb6e0 --- /dev/null +++ b/libstdc++-v3/testsuite/ext/pool_allocator/check_deallocate_null.cc @@ -0,0 +1,32 @@ +// +// 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_deallocate_null(); + return 0; +} + diff --git a/libstdc++-v3/testsuite/testsuite_allocator.h b/libstdc++-v3/testsuite/testsuite_allocator.h index 7d373aa08f9..ecb210e1fde 100644 --- a/libstdc++-v3/testsuite/testsuite_allocator.h +++ b/libstdc++-v3/testsuite/testsuite_allocator.h @@ -1,7 +1,7 @@ // -*- C++ -*- // Testing allocator for the C++ library testsuite. // -// Copyright (C) 2002, 2003 Free Software Foundation, Inc. +// Copyright (C) 2002, 2003, 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 @@ -181,20 +181,29 @@ namespace __gnu_test check_construct_destroy(const char* tag, int expected_c, int expected_d); template - bool check_new() - { - bool test __attribute__((unused)) = true; - Alloc a; - typename Alloc::pointer p = a.allocate(10); - if (uses_global_new_and_delete) - test &= ( requested >= (10 * 15 * sizeof(long)) ); + bool + check_new(Alloc a = Alloc()) + { + bool test __attribute__((unused)) = true; + typename Alloc::pointer p = a.allocate(10); + if (uses_global_new_and_delete) + test &= ( requested >= (10 * 15 * sizeof(long)) ); + + test &= ( new_called == uses_global_new_and_delete ); + a.deallocate(p, 10); + test &= ( delete_called == uses_global_new_and_delete ); + + return test; + } - test &= ( new_called == uses_global_new_and_delete ); - a.deallocate(p, 10); - test &= ( delete_called == uses_global_new_and_delete ); - - return test; - } + template + bool + check_deallocate_null() + { + // Let's not core here... + Alloc a; + a.deallocate(NULL, 10); + } }; // namespace __gnu_test #endif // _GLIBCXX_TESTSUITE_ALLOCATOR_H