xref: /minix3/external/bsd/libc++/dist/libcxx/test/support/count_new.hpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc #ifndef COUNT_NEW_HPP
2*0a6a1f1dSLionel Sambuc #define COUNT_NEW_HPP
3*0a6a1f1dSLionel Sambuc 
4*0a6a1f1dSLionel Sambuc # include <cstdlib>
5*0a6a1f1dSLionel Sambuc # include <cassert>
6*0a6a1f1dSLionel Sambuc # include <new>
7*0a6a1f1dSLionel Sambuc 
8*0a6a1f1dSLionel Sambuc #ifndef __has_feature
9*0a6a1f1dSLionel Sambuc #  define __has_feature(x) 0
10*0a6a1f1dSLionel Sambuc #endif
11*0a6a1f1dSLionel Sambuc 
12*0a6a1f1dSLionel Sambuc #if  __has_feature(address_sanitizer) \
13*0a6a1f1dSLionel Sambuc   || __has_feature(memory_sanitizer) \
14*0a6a1f1dSLionel Sambuc   || __has_feature(thread_sanitizer)
15*0a6a1f1dSLionel Sambuc #define DISABLE_NEW_COUNT
16*0a6a1f1dSLionel Sambuc #endif
17*0a6a1f1dSLionel Sambuc 
18*0a6a1f1dSLionel Sambuc class MemCounter
19*0a6a1f1dSLionel Sambuc {
20*0a6a1f1dSLionel Sambuc public:
21*0a6a1f1dSLionel Sambuc     // Make MemCounter super hard to accidentally construct or copy.
22*0a6a1f1dSLionel Sambuc     class MemCounterCtorArg_ {};
MemCounter(MemCounterCtorArg_)23*0a6a1f1dSLionel Sambuc     explicit MemCounter(MemCounterCtorArg_) { reset(); }
24*0a6a1f1dSLionel Sambuc 
25*0a6a1f1dSLionel Sambuc private:
26*0a6a1f1dSLionel Sambuc     MemCounter(MemCounter const &);
27*0a6a1f1dSLionel Sambuc     MemCounter & operator=(MemCounter const &);
28*0a6a1f1dSLionel Sambuc 
29*0a6a1f1dSLionel Sambuc public:
30*0a6a1f1dSLionel Sambuc     // All checks return true when disable_checking is enabled.
31*0a6a1f1dSLionel Sambuc     static const bool disable_checking;
32*0a6a1f1dSLionel Sambuc 
33*0a6a1f1dSLionel Sambuc     // Disallow any allocations from occurring. Useful for testing that
34*0a6a1f1dSLionel Sambuc     // code doesn't perform any allocations.
35*0a6a1f1dSLionel Sambuc     bool disable_allocations;
36*0a6a1f1dSLionel Sambuc 
37*0a6a1f1dSLionel Sambuc     int outstanding_new;
38*0a6a1f1dSLionel Sambuc     int new_called;
39*0a6a1f1dSLionel Sambuc     int delete_called;
40*0a6a1f1dSLionel Sambuc     int last_new_size;
41*0a6a1f1dSLionel Sambuc 
42*0a6a1f1dSLionel Sambuc     int outstanding_array_new;
43*0a6a1f1dSLionel Sambuc     int new_array_called;
44*0a6a1f1dSLionel Sambuc     int delete_array_called;
45*0a6a1f1dSLionel Sambuc     int last_new_array_size;
46*0a6a1f1dSLionel Sambuc 
47*0a6a1f1dSLionel Sambuc public:
newCalled(std::size_t s)48*0a6a1f1dSLionel Sambuc     void newCalled(std::size_t s)
49*0a6a1f1dSLionel Sambuc     {
50*0a6a1f1dSLionel Sambuc         assert(disable_allocations == false);
51*0a6a1f1dSLionel Sambuc         assert(s);
52*0a6a1f1dSLionel Sambuc         ++new_called;
53*0a6a1f1dSLionel Sambuc         ++outstanding_new;
54*0a6a1f1dSLionel Sambuc         last_new_size = s;
55*0a6a1f1dSLionel Sambuc     }
56*0a6a1f1dSLionel Sambuc 
deleteCalled(void * p)57*0a6a1f1dSLionel Sambuc     void deleteCalled(void * p)
58*0a6a1f1dSLionel Sambuc     {
59*0a6a1f1dSLionel Sambuc         assert(p);
60*0a6a1f1dSLionel Sambuc         --outstanding_new;
61*0a6a1f1dSLionel Sambuc         ++delete_called;
62*0a6a1f1dSLionel Sambuc     }
63*0a6a1f1dSLionel Sambuc 
newArrayCalled(std::size_t s)64*0a6a1f1dSLionel Sambuc     void newArrayCalled(std::size_t s)
65*0a6a1f1dSLionel Sambuc     {
66*0a6a1f1dSLionel Sambuc         assert(disable_allocations == false);
67*0a6a1f1dSLionel Sambuc         assert(s);
68*0a6a1f1dSLionel Sambuc         ++outstanding_array_new;
69*0a6a1f1dSLionel Sambuc         ++new_array_called;
70*0a6a1f1dSLionel Sambuc         last_new_array_size = s;
71*0a6a1f1dSLionel Sambuc     }
72*0a6a1f1dSLionel Sambuc 
deleteArrayCalled(void * p)73*0a6a1f1dSLionel Sambuc     void deleteArrayCalled(void * p)
74*0a6a1f1dSLionel Sambuc     {
75*0a6a1f1dSLionel Sambuc         assert(p);
76*0a6a1f1dSLionel Sambuc         --outstanding_array_new;
77*0a6a1f1dSLionel Sambuc         ++delete_array_called;
78*0a6a1f1dSLionel Sambuc     }
79*0a6a1f1dSLionel Sambuc 
disableAllocations()80*0a6a1f1dSLionel Sambuc     void disableAllocations()
81*0a6a1f1dSLionel Sambuc     {
82*0a6a1f1dSLionel Sambuc         disable_allocations = true;
83*0a6a1f1dSLionel Sambuc     }
84*0a6a1f1dSLionel Sambuc 
enableAllocations()85*0a6a1f1dSLionel Sambuc     void enableAllocations()
86*0a6a1f1dSLionel Sambuc     {
87*0a6a1f1dSLionel Sambuc         disable_allocations = false;
88*0a6a1f1dSLionel Sambuc     }
89*0a6a1f1dSLionel Sambuc 
reset()90*0a6a1f1dSLionel Sambuc     void reset()
91*0a6a1f1dSLionel Sambuc     {
92*0a6a1f1dSLionel Sambuc         disable_allocations = false;
93*0a6a1f1dSLionel Sambuc 
94*0a6a1f1dSLionel Sambuc         outstanding_new = 0;
95*0a6a1f1dSLionel Sambuc         new_called = 0;
96*0a6a1f1dSLionel Sambuc         delete_called = 0;
97*0a6a1f1dSLionel Sambuc         last_new_size = 0;
98*0a6a1f1dSLionel Sambuc 
99*0a6a1f1dSLionel Sambuc         outstanding_array_new = 0;
100*0a6a1f1dSLionel Sambuc         new_array_called = 0;
101*0a6a1f1dSLionel Sambuc         delete_array_called = 0;
102*0a6a1f1dSLionel Sambuc         last_new_array_size = 0;
103*0a6a1f1dSLionel Sambuc     }
104*0a6a1f1dSLionel Sambuc 
105*0a6a1f1dSLionel Sambuc public:
checkOutstandingNewEq(int n) const106*0a6a1f1dSLionel Sambuc     bool checkOutstandingNewEq(int n) const
107*0a6a1f1dSLionel Sambuc     {
108*0a6a1f1dSLionel Sambuc         return disable_checking || n == outstanding_new;
109*0a6a1f1dSLionel Sambuc     }
110*0a6a1f1dSLionel Sambuc 
checkOutstandingNewNotEq(int n) const111*0a6a1f1dSLionel Sambuc     bool checkOutstandingNewNotEq(int n) const
112*0a6a1f1dSLionel Sambuc     {
113*0a6a1f1dSLionel Sambuc         return disable_checking || n != outstanding_new;
114*0a6a1f1dSLionel Sambuc     }
115*0a6a1f1dSLionel Sambuc 
checkNewCalledEq(int n) const116*0a6a1f1dSLionel Sambuc     bool checkNewCalledEq(int n) const
117*0a6a1f1dSLionel Sambuc     {
118*0a6a1f1dSLionel Sambuc         return disable_checking || n == new_called;
119*0a6a1f1dSLionel Sambuc     }
120*0a6a1f1dSLionel Sambuc 
checkNewCalledNotEq(int n) const121*0a6a1f1dSLionel Sambuc     bool checkNewCalledNotEq(int n) const
122*0a6a1f1dSLionel Sambuc     {
123*0a6a1f1dSLionel Sambuc         return disable_checking || n != new_called;
124*0a6a1f1dSLionel Sambuc     }
125*0a6a1f1dSLionel Sambuc 
checkDeleteCalledEq(int n) const126*0a6a1f1dSLionel Sambuc     bool checkDeleteCalledEq(int n) const
127*0a6a1f1dSLionel Sambuc     {
128*0a6a1f1dSLionel Sambuc         return disable_checking || n == delete_called;
129*0a6a1f1dSLionel Sambuc     }
130*0a6a1f1dSLionel Sambuc 
checkDeleteCalledNotEq(int n) const131*0a6a1f1dSLionel Sambuc     bool checkDeleteCalledNotEq(int n) const
132*0a6a1f1dSLionel Sambuc     {
133*0a6a1f1dSLionel Sambuc         return disable_checking || n != delete_called;
134*0a6a1f1dSLionel Sambuc     }
135*0a6a1f1dSLionel Sambuc 
checkLastNewSizeEq(int n) const136*0a6a1f1dSLionel Sambuc     bool checkLastNewSizeEq(int n) const
137*0a6a1f1dSLionel Sambuc     {
138*0a6a1f1dSLionel Sambuc         return disable_checking || n == last_new_size;
139*0a6a1f1dSLionel Sambuc     }
140*0a6a1f1dSLionel Sambuc 
checkLastNewSizeNotEq(int n) const141*0a6a1f1dSLionel Sambuc     bool checkLastNewSizeNotEq(int n) const
142*0a6a1f1dSLionel Sambuc     {
143*0a6a1f1dSLionel Sambuc         return disable_checking || n != last_new_size;
144*0a6a1f1dSLionel Sambuc     }
145*0a6a1f1dSLionel Sambuc 
checkOutstandingArrayNewEq(int n) const146*0a6a1f1dSLionel Sambuc     bool checkOutstandingArrayNewEq(int n) const
147*0a6a1f1dSLionel Sambuc     {
148*0a6a1f1dSLionel Sambuc         return disable_checking || n == outstanding_array_new;
149*0a6a1f1dSLionel Sambuc     }
150*0a6a1f1dSLionel Sambuc 
checkOutstandingArrayNewNotEq(int n) const151*0a6a1f1dSLionel Sambuc     bool checkOutstandingArrayNewNotEq(int n) const
152*0a6a1f1dSLionel Sambuc     {
153*0a6a1f1dSLionel Sambuc         return disable_checking || n != outstanding_array_new;
154*0a6a1f1dSLionel Sambuc     }
155*0a6a1f1dSLionel Sambuc 
checkNewArrayCalledEq(int n) const156*0a6a1f1dSLionel Sambuc     bool checkNewArrayCalledEq(int n) const
157*0a6a1f1dSLionel Sambuc     {
158*0a6a1f1dSLionel Sambuc         return disable_checking || n == new_array_called;
159*0a6a1f1dSLionel Sambuc     }
160*0a6a1f1dSLionel Sambuc 
checkNewArrayCalledNotEq(int n) const161*0a6a1f1dSLionel Sambuc     bool checkNewArrayCalledNotEq(int n) const
162*0a6a1f1dSLionel Sambuc     {
163*0a6a1f1dSLionel Sambuc         return disable_checking || n != new_array_called;
164*0a6a1f1dSLionel Sambuc     }
165*0a6a1f1dSLionel Sambuc 
checkDeleteArrayCalledEq(int n) const166*0a6a1f1dSLionel Sambuc     bool checkDeleteArrayCalledEq(int n) const
167*0a6a1f1dSLionel Sambuc     {
168*0a6a1f1dSLionel Sambuc         return disable_checking || n == delete_array_called;
169*0a6a1f1dSLionel Sambuc     }
170*0a6a1f1dSLionel Sambuc 
checkDeleteArrayCalledNotEq(int n) const171*0a6a1f1dSLionel Sambuc     bool checkDeleteArrayCalledNotEq(int n) const
172*0a6a1f1dSLionel Sambuc     {
173*0a6a1f1dSLionel Sambuc         return disable_checking || n != delete_array_called;
174*0a6a1f1dSLionel Sambuc     }
175*0a6a1f1dSLionel Sambuc 
checkLastNewArraySizeEq(int n) const176*0a6a1f1dSLionel Sambuc     bool checkLastNewArraySizeEq(int n) const
177*0a6a1f1dSLionel Sambuc     {
178*0a6a1f1dSLionel Sambuc         return disable_checking || n == last_new_array_size;
179*0a6a1f1dSLionel Sambuc     }
180*0a6a1f1dSLionel Sambuc 
checkLastNewArraySizeNotEq(int n) const181*0a6a1f1dSLionel Sambuc     bool checkLastNewArraySizeNotEq(int n) const
182*0a6a1f1dSLionel Sambuc     {
183*0a6a1f1dSLionel Sambuc         return disable_checking || n != last_new_array_size;
184*0a6a1f1dSLionel Sambuc     }
185*0a6a1f1dSLionel Sambuc };
186*0a6a1f1dSLionel Sambuc 
187*0a6a1f1dSLionel Sambuc #ifdef DISABLE_NEW_COUNT
188*0a6a1f1dSLionel Sambuc   const bool MemCounter::disable_checking = true;
189*0a6a1f1dSLionel Sambuc #else
190*0a6a1f1dSLionel Sambuc   const bool MemCounter::disable_checking = false;
191*0a6a1f1dSLionel Sambuc #endif
192*0a6a1f1dSLionel Sambuc 
193*0a6a1f1dSLionel Sambuc MemCounter globalMemCounter((MemCounter::MemCounterCtorArg_()));
194*0a6a1f1dSLionel Sambuc 
195*0a6a1f1dSLionel Sambuc #ifndef DISABLE_NEW_COUNT
operator new(std::size_t s)196*0a6a1f1dSLionel Sambuc void* operator new(std::size_t s) throw(std::bad_alloc)
197*0a6a1f1dSLionel Sambuc {
198*0a6a1f1dSLionel Sambuc     globalMemCounter.newCalled(s);
199*0a6a1f1dSLionel Sambuc     return std::malloc(s);
200*0a6a1f1dSLionel Sambuc }
201*0a6a1f1dSLionel Sambuc 
operator delete(void * p)202*0a6a1f1dSLionel Sambuc void  operator delete(void* p) throw()
203*0a6a1f1dSLionel Sambuc {
204*0a6a1f1dSLionel Sambuc     globalMemCounter.deleteCalled(p);
205*0a6a1f1dSLionel Sambuc     std::free(p);
206*0a6a1f1dSLionel Sambuc }
207*0a6a1f1dSLionel Sambuc 
208*0a6a1f1dSLionel Sambuc 
operator new[](std::size_t s)209*0a6a1f1dSLionel Sambuc void* operator new[](std::size_t s) throw(std::bad_alloc)
210*0a6a1f1dSLionel Sambuc {
211*0a6a1f1dSLionel Sambuc     globalMemCounter.newArrayCalled(s);
212*0a6a1f1dSLionel Sambuc     return operator new(s);
213*0a6a1f1dSLionel Sambuc }
214*0a6a1f1dSLionel Sambuc 
215*0a6a1f1dSLionel Sambuc 
operator delete[](void * p)216*0a6a1f1dSLionel Sambuc void operator delete[](void* p) throw()
217*0a6a1f1dSLionel Sambuc {
218*0a6a1f1dSLionel Sambuc     globalMemCounter.deleteArrayCalled(p);
219*0a6a1f1dSLionel Sambuc     operator delete(p);
220*0a6a1f1dSLionel Sambuc }
221*0a6a1f1dSLionel Sambuc 
222*0a6a1f1dSLionel Sambuc #endif // DISABLE_NEW_COUNT
223*0a6a1f1dSLionel Sambuc 
224*0a6a1f1dSLionel Sambuc 
225*0a6a1f1dSLionel Sambuc struct DisableAllocationGuard {
DisableAllocationGuardDisableAllocationGuard226*0a6a1f1dSLionel Sambuc     explicit DisableAllocationGuard(bool disable = true) : m_disabled(disable)
227*0a6a1f1dSLionel Sambuc     {
228*0a6a1f1dSLionel Sambuc         // Don't re-disable if already disabled.
229*0a6a1f1dSLionel Sambuc         if (globalMemCounter.disable_allocations == true) m_disabled = false;
230*0a6a1f1dSLionel Sambuc         if (m_disabled) globalMemCounter.disableAllocations();
231*0a6a1f1dSLionel Sambuc     }
232*0a6a1f1dSLionel Sambuc 
releaseDisableAllocationGuard233*0a6a1f1dSLionel Sambuc     void release() {
234*0a6a1f1dSLionel Sambuc         if (m_disabled) globalMemCounter.enableAllocations();
235*0a6a1f1dSLionel Sambuc         m_disabled = false;
236*0a6a1f1dSLionel Sambuc     }
237*0a6a1f1dSLionel Sambuc 
~DisableAllocationGuardDisableAllocationGuard238*0a6a1f1dSLionel Sambuc     ~DisableAllocationGuard() {
239*0a6a1f1dSLionel Sambuc         release();
240*0a6a1f1dSLionel Sambuc     }
241*0a6a1f1dSLionel Sambuc 
242*0a6a1f1dSLionel Sambuc private:
243*0a6a1f1dSLionel Sambuc     bool m_disabled;
244*0a6a1f1dSLionel Sambuc 
245*0a6a1f1dSLionel Sambuc     DisableAllocationGuard(DisableAllocationGuard const&);
246*0a6a1f1dSLionel Sambuc     DisableAllocationGuard& operator=(DisableAllocationGuard const&);
247*0a6a1f1dSLionel Sambuc };
248*0a6a1f1dSLionel Sambuc 
249*0a6a1f1dSLionel Sambuc #endif /* COUNT_NEW_HPP */
250