1 // 2 // Copyright (C) 2007-2020 Free Software Foundation, Inc. 3 // 4 // This file is part of the GNU ISO C++ Library. This library is free 5 // software; you can redistribute it and/or modify it under the 6 // terms of the GNU General Public License as published by the 7 // Free Software Foundation; either version 3, or (at your option) 8 // any later version. 9 // 10 // This library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License along 16 // with this library; see the file COPYING3. If not see 17 // <http://www.gnu.org/licenses/>. 18 19 #include <exception> 20 #include <stdexcept> 21 #include <cstdlib> 22 #include <cstdio> 23 #include <testsuite_hooks.h> 24 25 namespace __gnu_test 26 { 27 struct counter_error : public std::exception { }; 28 29 struct counter 30 { 31 std::size_t _M_count; 32 bool _M_throw; 33 countercounter34 counter() : _M_count(0), _M_throw(true) { } 35 THROWcounter36 ~counter() THROW (counter_error) 37 { 38 if (_M_throw && _M_count != 0) 39 throw counter_error(); 40 } 41 42 static void incrementcounter43 increment() { get()._M_count++; } 44 45 static void decrementcounter46 decrement() { get()._M_count--; } 47 48 static counter& getcounter49 get() 50 { 51 static counter g; 52 return g; 53 } 54 55 static std::size_t countcounter56 count() { return get()._M_count; } 57 58 static void exceptionscounter59 exceptions(bool __b) { get()._M_throw = __b; } 60 }; 61 62 template<typename Alloc, bool uses_global_new> 63 bool 64 check_new(Alloc a = Alloc()) 65 { 66 __gnu_test::counter::exceptions(false); 67 (void) a.allocate(10); 68 const bool __b((__gnu_test::counter::count() > 0) == uses_global_new); 69 if (!__b) 70 throw std::logic_error("counter not incremented"); 71 return __b; 72 } 73 74 template<typename Alloc, bool uses_global_delete> 75 bool 76 check_delete(Alloc a = Alloc()) 77 { 78 __gnu_test::counter::exceptions(false); 79 #if __cplusplus >= 201103L 80 auto p = a.allocate(10); 81 #else 82 typename Alloc::pointer p = a.allocate(10); 83 #endif 84 const std::size_t count1 = __gnu_test::counter::count(); 85 a.deallocate(p, 10); 86 const std::size_t count2 = __gnu_test::counter::count(); 87 const bool __b((count2 < count1) == uses_global_delete); 88 if (!__b) 89 throw std::logic_error("counter not decremented"); 90 return __b; 91 } 92 } // namespace __gnu_test 93 new(std::size_t size)94void* operator new(std::size_t size) THROW(std::bad_alloc) 95 { 96 std::printf("operator new is called \n"); 97 void* p = std::malloc(size); 98 if (!p) 99 throw std::bad_alloc(); 100 __gnu_test::counter::increment(); 101 return p; 102 } 103 delete(void * p)104void operator delete(void* p) throw() 105 { 106 std::printf("operator delete is called \n"); 107 if (p) 108 { 109 std::free(p); 110 __gnu_test::counter::decrement(); 111 112 std::size_t count = __gnu_test::counter::count(); 113 if (count == 0) 114 std::printf("All memory released \n"); 115 else 116 std::printf("%lu allocations to be released \n", (unsigned long)count); 117 } 118 } 119