1 //
2 // Copyright (C) 2007-2021 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     std::size_t _M_increments, _M_decrements;
33     bool	_M_throw;
34 
countercounter35     counter() : _M_count(0), _M_throw(true) { }
36 
THROWcounter37     ~counter() THROW (counter_error)
38     {
39       if (_M_throw && _M_count != 0)
40 	throw counter_error();
41     }
42 
43     static void
incrementcounter44     increment()
45     {
46       counter& cntr = get();
47       cntr._M_count++;
48       cntr._M_increments++;
49     }
50 
51     static void
decrementcounter52     decrement()
53     {
54       counter& cntr = get();
55       cntr._M_count--;
56       cntr._M_decrements++;
57     }
58 
59     static counter&
getcounter60     get()
61     {
62       static counter g;
63       return g;
64     }
65 
66     static std::size_t
countcounter67     count() { return get()._M_count; }
68 
69     static void
exceptionscounter70     exceptions(bool __b) { get()._M_throw = __b; }
71 
72     static void
resetcounter73     reset()
74     {
75       counter& cntr = get();
76       cntr._M_increments = cntr._M_decrements = 0;
77     }
78   };
79 
80   template<typename Alloc, bool uses_global_new>
81     bool
82     check_new(Alloc a = Alloc())
83     {
84       __gnu_test::counter::exceptions(false);
85       (void) a.allocate(10);
86       const bool __b((__gnu_test::counter::count() > 0) == uses_global_new);
87       if (!__b)
88 	throw std::logic_error("counter not incremented");
89       return __b;
90     }
91 
92   template<typename Alloc, bool uses_global_delete>
93     bool
94     check_delete(Alloc a = Alloc())
95     {
96       __gnu_test::counter::exceptions(false);
97 #if __cplusplus >= 201103L
98       auto p = a.allocate(10);
99 #else
100       typename Alloc::pointer p = a.allocate(10);
101 #endif
102       const std::size_t count1 = __gnu_test::counter::count();
103       a.deallocate(p, 10);
104       const std::size_t count2 = __gnu_test::counter::count();
105       const bool __b((count2 < count1) == uses_global_delete);
106       if (!__b)
107 	throw std::logic_error("counter not decremented");
108       return __b;
109     }
110 } // namespace __gnu_test
111 
new(std::size_t size)112 void* operator new(std::size_t size) THROW(std::bad_alloc)
113 {
114   std::printf("operator new is called \n");
115   void* p = std::malloc(size);
116   if (!p)
117     throw std::bad_alloc();
118   __gnu_test::counter::increment();
119   return p;
120 }
121 
delete(void * p)122 void operator delete(void* p) throw()
123 {
124   std::printf("operator delete is called \n");
125   if (p)
126     {
127       std::free(p);
128       __gnu_test::counter::decrement();
129 
130       std::size_t count = __gnu_test::counter::count();
131       if (count == 0)
132 	std::printf("All memory released \n");
133       else
134 	std::printf("%lu allocations to be released \n", (unsigned long)count);
135     }
136 }
137 
138 #if __cpp_sized_deallocation
delete(void * p,std::size_t)139 void operator delete(void* p, std::size_t) throw() { ::operator delete(p); }
140 #endif
141