xref: /aosp_15_r20/external/libcxx/test/support/count_new.hpp (revision 58b9f456b02922dfdb1fad8a988d5fd8765ecb80)
1*58b9f456SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
2*58b9f456SAndroid Build Coastguard Worker //
3*58b9f456SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*58b9f456SAndroid Build Coastguard Worker //
5*58b9f456SAndroid Build Coastguard Worker // This file is dual licensed under the MIT and the University of Illinois Open
6*58b9f456SAndroid Build Coastguard Worker // Source Licenses. See LICENSE.TXT for details.
7*58b9f456SAndroid Build Coastguard Worker //
8*58b9f456SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*58b9f456SAndroid Build Coastguard Worker 
10*58b9f456SAndroid Build Coastguard Worker #ifndef COUNT_NEW_HPP
11*58b9f456SAndroid Build Coastguard Worker #define COUNT_NEW_HPP
12*58b9f456SAndroid Build Coastguard Worker 
13*58b9f456SAndroid Build Coastguard Worker # include <cstdlib>
14*58b9f456SAndroid Build Coastguard Worker # include <cassert>
15*58b9f456SAndroid Build Coastguard Worker # include <new>
16*58b9f456SAndroid Build Coastguard Worker 
17*58b9f456SAndroid Build Coastguard Worker #include "test_macros.h"
18*58b9f456SAndroid Build Coastguard Worker 
19*58b9f456SAndroid Build Coastguard Worker #if defined(TEST_HAS_SANITIZERS)
20*58b9f456SAndroid Build Coastguard Worker #define DISABLE_NEW_COUNT
21*58b9f456SAndroid Build Coastguard Worker #endif
22*58b9f456SAndroid Build Coastguard Worker 
23*58b9f456SAndroid Build Coastguard Worker namespace detail
24*58b9f456SAndroid Build Coastguard Worker {
25*58b9f456SAndroid Build Coastguard Worker    TEST_NORETURN
throw_bad_alloc_helper()26*58b9f456SAndroid Build Coastguard Worker    inline void throw_bad_alloc_helper() {
27*58b9f456SAndroid Build Coastguard Worker #ifndef TEST_HAS_NO_EXCEPTIONS
28*58b9f456SAndroid Build Coastguard Worker        throw std::bad_alloc();
29*58b9f456SAndroid Build Coastguard Worker #else
30*58b9f456SAndroid Build Coastguard Worker        std::abort();
31*58b9f456SAndroid Build Coastguard Worker #endif
32*58b9f456SAndroid Build Coastguard Worker    }
33*58b9f456SAndroid Build Coastguard Worker }
34*58b9f456SAndroid Build Coastguard Worker 
35*58b9f456SAndroid Build Coastguard Worker class MemCounter
36*58b9f456SAndroid Build Coastguard Worker {
37*58b9f456SAndroid Build Coastguard Worker public:
38*58b9f456SAndroid Build Coastguard Worker     // Make MemCounter super hard to accidentally construct or copy.
39*58b9f456SAndroid Build Coastguard Worker     class MemCounterCtorArg_ {};
MemCounter(MemCounterCtorArg_)40*58b9f456SAndroid Build Coastguard Worker     explicit MemCounter(MemCounterCtorArg_) { reset(); }
41*58b9f456SAndroid Build Coastguard Worker 
42*58b9f456SAndroid Build Coastguard Worker private:
43*58b9f456SAndroid Build Coastguard Worker     MemCounter(MemCounter const &);
44*58b9f456SAndroid Build Coastguard Worker     MemCounter & operator=(MemCounter const &);
45*58b9f456SAndroid Build Coastguard Worker 
46*58b9f456SAndroid Build Coastguard Worker public:
47*58b9f456SAndroid Build Coastguard Worker     // All checks return true when disable_checking is enabled.
48*58b9f456SAndroid Build Coastguard Worker     static const bool disable_checking;
49*58b9f456SAndroid Build Coastguard Worker 
50*58b9f456SAndroid Build Coastguard Worker     // Disallow any allocations from occurring. Useful for testing that
51*58b9f456SAndroid Build Coastguard Worker     // code doesn't perform any allocations.
52*58b9f456SAndroid Build Coastguard Worker     bool disable_allocations;
53*58b9f456SAndroid Build Coastguard Worker 
54*58b9f456SAndroid Build Coastguard Worker     // number of allocations to throw after. Default (unsigned)-1. If
55*58b9f456SAndroid Build Coastguard Worker     // throw_after has the default value it will never be decremented.
56*58b9f456SAndroid Build Coastguard Worker     static const unsigned never_throw_value = static_cast<unsigned>(-1);
57*58b9f456SAndroid Build Coastguard Worker     unsigned throw_after;
58*58b9f456SAndroid Build Coastguard Worker 
59*58b9f456SAndroid Build Coastguard Worker     int outstanding_new;
60*58b9f456SAndroid Build Coastguard Worker     int new_called;
61*58b9f456SAndroid Build Coastguard Worker     int delete_called;
62*58b9f456SAndroid Build Coastguard Worker     int aligned_new_called;
63*58b9f456SAndroid Build Coastguard Worker     int aligned_delete_called;
64*58b9f456SAndroid Build Coastguard Worker     std::size_t last_new_size;
65*58b9f456SAndroid Build Coastguard Worker     std::size_t last_new_align;
66*58b9f456SAndroid Build Coastguard Worker     std::size_t last_delete_align;
67*58b9f456SAndroid Build Coastguard Worker 
68*58b9f456SAndroid Build Coastguard Worker     int outstanding_array_new;
69*58b9f456SAndroid Build Coastguard Worker     int new_array_called;
70*58b9f456SAndroid Build Coastguard Worker     int delete_array_called;
71*58b9f456SAndroid Build Coastguard Worker     int aligned_new_array_called;
72*58b9f456SAndroid Build Coastguard Worker     int aligned_delete_array_called;
73*58b9f456SAndroid Build Coastguard Worker     std::size_t last_new_array_size;
74*58b9f456SAndroid Build Coastguard Worker     std::size_t last_new_array_align;
75*58b9f456SAndroid Build Coastguard Worker     std::size_t last_delete_array_align;
76*58b9f456SAndroid Build Coastguard Worker 
77*58b9f456SAndroid Build Coastguard Worker public:
newCalled(std::size_t s)78*58b9f456SAndroid Build Coastguard Worker     void newCalled(std::size_t s)
79*58b9f456SAndroid Build Coastguard Worker     {
80*58b9f456SAndroid Build Coastguard Worker         assert(disable_allocations == false);
81*58b9f456SAndroid Build Coastguard Worker         assert(s);
82*58b9f456SAndroid Build Coastguard Worker         if (throw_after == 0) {
83*58b9f456SAndroid Build Coastguard Worker             throw_after = never_throw_value;
84*58b9f456SAndroid Build Coastguard Worker             detail::throw_bad_alloc_helper();
85*58b9f456SAndroid Build Coastguard Worker         } else if (throw_after != never_throw_value) {
86*58b9f456SAndroid Build Coastguard Worker             --throw_after;
87*58b9f456SAndroid Build Coastguard Worker         }
88*58b9f456SAndroid Build Coastguard Worker         ++new_called;
89*58b9f456SAndroid Build Coastguard Worker         ++outstanding_new;
90*58b9f456SAndroid Build Coastguard Worker         last_new_size = s;
91*58b9f456SAndroid Build Coastguard Worker     }
92*58b9f456SAndroid Build Coastguard Worker 
alignedNewCalled(std::size_t s,std::size_t a)93*58b9f456SAndroid Build Coastguard Worker     void alignedNewCalled(std::size_t s, std::size_t a) {
94*58b9f456SAndroid Build Coastguard Worker       newCalled(s);
95*58b9f456SAndroid Build Coastguard Worker       ++aligned_new_called;
96*58b9f456SAndroid Build Coastguard Worker       last_new_align = a;
97*58b9f456SAndroid Build Coastguard Worker     }
98*58b9f456SAndroid Build Coastguard Worker 
deleteCalled(void * p)99*58b9f456SAndroid Build Coastguard Worker     void deleteCalled(void * p)
100*58b9f456SAndroid Build Coastguard Worker     {
101*58b9f456SAndroid Build Coastguard Worker         assert(p);
102*58b9f456SAndroid Build Coastguard Worker         --outstanding_new;
103*58b9f456SAndroid Build Coastguard Worker         ++delete_called;
104*58b9f456SAndroid Build Coastguard Worker     }
105*58b9f456SAndroid Build Coastguard Worker 
alignedDeleteCalled(void * p,std::size_t a)106*58b9f456SAndroid Build Coastguard Worker     void alignedDeleteCalled(void *p, std::size_t a) {
107*58b9f456SAndroid Build Coastguard Worker       deleteCalled(p);
108*58b9f456SAndroid Build Coastguard Worker       ++aligned_delete_called;
109*58b9f456SAndroid Build Coastguard Worker       last_delete_align = a;
110*58b9f456SAndroid Build Coastguard Worker     }
111*58b9f456SAndroid Build Coastguard Worker 
newArrayCalled(std::size_t s)112*58b9f456SAndroid Build Coastguard Worker     void newArrayCalled(std::size_t s)
113*58b9f456SAndroid Build Coastguard Worker     {
114*58b9f456SAndroid Build Coastguard Worker         assert(disable_allocations == false);
115*58b9f456SAndroid Build Coastguard Worker         assert(s);
116*58b9f456SAndroid Build Coastguard Worker         if (throw_after == 0) {
117*58b9f456SAndroid Build Coastguard Worker             throw_after = never_throw_value;
118*58b9f456SAndroid Build Coastguard Worker             detail::throw_bad_alloc_helper();
119*58b9f456SAndroid Build Coastguard Worker         } else {
120*58b9f456SAndroid Build Coastguard Worker             // don't decrement throw_after here. newCalled will end up doing that.
121*58b9f456SAndroid Build Coastguard Worker         }
122*58b9f456SAndroid Build Coastguard Worker         ++outstanding_array_new;
123*58b9f456SAndroid Build Coastguard Worker         ++new_array_called;
124*58b9f456SAndroid Build Coastguard Worker         last_new_array_size = s;
125*58b9f456SAndroid Build Coastguard Worker     }
126*58b9f456SAndroid Build Coastguard Worker 
alignedNewArrayCalled(std::size_t s,std::size_t a)127*58b9f456SAndroid Build Coastguard Worker     void alignedNewArrayCalled(std::size_t s, std::size_t a) {
128*58b9f456SAndroid Build Coastguard Worker       newArrayCalled(s);
129*58b9f456SAndroid Build Coastguard Worker       ++aligned_new_array_called;
130*58b9f456SAndroid Build Coastguard Worker       last_new_array_align = a;
131*58b9f456SAndroid Build Coastguard Worker     }
132*58b9f456SAndroid Build Coastguard Worker 
deleteArrayCalled(void * p)133*58b9f456SAndroid Build Coastguard Worker     void deleteArrayCalled(void * p)
134*58b9f456SAndroid Build Coastguard Worker     {
135*58b9f456SAndroid Build Coastguard Worker         assert(p);
136*58b9f456SAndroid Build Coastguard Worker         --outstanding_array_new;
137*58b9f456SAndroid Build Coastguard Worker         ++delete_array_called;
138*58b9f456SAndroid Build Coastguard Worker     }
139*58b9f456SAndroid Build Coastguard Worker 
alignedDeleteArrayCalled(void * p,std::size_t a)140*58b9f456SAndroid Build Coastguard Worker     void alignedDeleteArrayCalled(void * p, std::size_t a) {
141*58b9f456SAndroid Build Coastguard Worker       deleteArrayCalled(p);
142*58b9f456SAndroid Build Coastguard Worker       ++aligned_delete_array_called;
143*58b9f456SAndroid Build Coastguard Worker       last_delete_array_align = a;
144*58b9f456SAndroid Build Coastguard Worker     }
145*58b9f456SAndroid Build Coastguard Worker 
disableAllocations()146*58b9f456SAndroid Build Coastguard Worker     void disableAllocations()
147*58b9f456SAndroid Build Coastguard Worker     {
148*58b9f456SAndroid Build Coastguard Worker         disable_allocations = true;
149*58b9f456SAndroid Build Coastguard Worker     }
150*58b9f456SAndroid Build Coastguard Worker 
enableAllocations()151*58b9f456SAndroid Build Coastguard Worker     void enableAllocations()
152*58b9f456SAndroid Build Coastguard Worker     {
153*58b9f456SAndroid Build Coastguard Worker         disable_allocations = false;
154*58b9f456SAndroid Build Coastguard Worker     }
155*58b9f456SAndroid Build Coastguard Worker 
reset()156*58b9f456SAndroid Build Coastguard Worker     void reset()
157*58b9f456SAndroid Build Coastguard Worker     {
158*58b9f456SAndroid Build Coastguard Worker         disable_allocations = false;
159*58b9f456SAndroid Build Coastguard Worker         throw_after = never_throw_value;
160*58b9f456SAndroid Build Coastguard Worker 
161*58b9f456SAndroid Build Coastguard Worker         outstanding_new = 0;
162*58b9f456SAndroid Build Coastguard Worker         new_called = 0;
163*58b9f456SAndroid Build Coastguard Worker         delete_called = 0;
164*58b9f456SAndroid Build Coastguard Worker         aligned_new_called = 0;
165*58b9f456SAndroid Build Coastguard Worker         aligned_delete_called = 0;
166*58b9f456SAndroid Build Coastguard Worker         last_new_size = 0;
167*58b9f456SAndroid Build Coastguard Worker         last_new_align = 0;
168*58b9f456SAndroid Build Coastguard Worker 
169*58b9f456SAndroid Build Coastguard Worker         outstanding_array_new = 0;
170*58b9f456SAndroid Build Coastguard Worker         new_array_called = 0;
171*58b9f456SAndroid Build Coastguard Worker         delete_array_called = 0;
172*58b9f456SAndroid Build Coastguard Worker         aligned_new_array_called = 0;
173*58b9f456SAndroid Build Coastguard Worker         aligned_delete_array_called = 0;
174*58b9f456SAndroid Build Coastguard Worker         last_new_array_size = 0;
175*58b9f456SAndroid Build Coastguard Worker         last_new_array_align = 0;
176*58b9f456SAndroid Build Coastguard Worker     }
177*58b9f456SAndroid Build Coastguard Worker 
178*58b9f456SAndroid Build Coastguard Worker public:
checkOutstandingNewEq(int n) const179*58b9f456SAndroid Build Coastguard Worker     bool checkOutstandingNewEq(int n) const
180*58b9f456SAndroid Build Coastguard Worker     {
181*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n == outstanding_new;
182*58b9f456SAndroid Build Coastguard Worker     }
183*58b9f456SAndroid Build Coastguard Worker 
checkOutstandingNewNotEq(int n) const184*58b9f456SAndroid Build Coastguard Worker     bool checkOutstandingNewNotEq(int n) const
185*58b9f456SAndroid Build Coastguard Worker     {
186*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n != outstanding_new;
187*58b9f456SAndroid Build Coastguard Worker     }
188*58b9f456SAndroid Build Coastguard Worker 
checkNewCalledEq(int n) const189*58b9f456SAndroid Build Coastguard Worker     bool checkNewCalledEq(int n) const
190*58b9f456SAndroid Build Coastguard Worker     {
191*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n == new_called;
192*58b9f456SAndroid Build Coastguard Worker     }
193*58b9f456SAndroid Build Coastguard Worker 
checkNewCalledNotEq(int n) const194*58b9f456SAndroid Build Coastguard Worker     bool checkNewCalledNotEq(int n) const
195*58b9f456SAndroid Build Coastguard Worker     {
196*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n != new_called;
197*58b9f456SAndroid Build Coastguard Worker     }
198*58b9f456SAndroid Build Coastguard Worker 
checkNewCalledGreaterThan(int n) const199*58b9f456SAndroid Build Coastguard Worker     bool checkNewCalledGreaterThan(int n) const
200*58b9f456SAndroid Build Coastguard Worker     {
201*58b9f456SAndroid Build Coastguard Worker         return disable_checking || new_called > n;
202*58b9f456SAndroid Build Coastguard Worker     }
203*58b9f456SAndroid Build Coastguard Worker 
checkDeleteCalledEq(int n) const204*58b9f456SAndroid Build Coastguard Worker     bool checkDeleteCalledEq(int n) const
205*58b9f456SAndroid Build Coastguard Worker     {
206*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n == delete_called;
207*58b9f456SAndroid Build Coastguard Worker     }
208*58b9f456SAndroid Build Coastguard Worker 
checkDeleteCalledNotEq(int n) const209*58b9f456SAndroid Build Coastguard Worker     bool checkDeleteCalledNotEq(int n) const
210*58b9f456SAndroid Build Coastguard Worker     {
211*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n != delete_called;
212*58b9f456SAndroid Build Coastguard Worker     }
213*58b9f456SAndroid Build Coastguard Worker 
checkAlignedNewCalledEq(int n) const214*58b9f456SAndroid Build Coastguard Worker     bool checkAlignedNewCalledEq(int n) const
215*58b9f456SAndroid Build Coastguard Worker     {
216*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n == aligned_new_called;
217*58b9f456SAndroid Build Coastguard Worker     }
218*58b9f456SAndroid Build Coastguard Worker 
checkAlignedNewCalledNotEq(int n) const219*58b9f456SAndroid Build Coastguard Worker     bool checkAlignedNewCalledNotEq(int n) const
220*58b9f456SAndroid Build Coastguard Worker     {
221*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n != aligned_new_called;
222*58b9f456SAndroid Build Coastguard Worker     }
223*58b9f456SAndroid Build Coastguard Worker 
checkAlignedNewCalledGreaterThan(int n) const224*58b9f456SAndroid Build Coastguard Worker     bool checkAlignedNewCalledGreaterThan(int n) const
225*58b9f456SAndroid Build Coastguard Worker     {
226*58b9f456SAndroid Build Coastguard Worker         return disable_checking || aligned_new_called > n;
227*58b9f456SAndroid Build Coastguard Worker     }
228*58b9f456SAndroid Build Coastguard Worker 
checkAlignedDeleteCalledEq(int n) const229*58b9f456SAndroid Build Coastguard Worker     bool checkAlignedDeleteCalledEq(int n) const
230*58b9f456SAndroid Build Coastguard Worker     {
231*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n == aligned_delete_called;
232*58b9f456SAndroid Build Coastguard Worker     }
233*58b9f456SAndroid Build Coastguard Worker 
checkAlignedDeleteCalledNotEq(int n) const234*58b9f456SAndroid Build Coastguard Worker     bool checkAlignedDeleteCalledNotEq(int n) const
235*58b9f456SAndroid Build Coastguard Worker     {
236*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n != aligned_delete_called;
237*58b9f456SAndroid Build Coastguard Worker     }
238*58b9f456SAndroid Build Coastguard Worker 
checkLastNewSizeEq(std::size_t n) const239*58b9f456SAndroid Build Coastguard Worker     bool checkLastNewSizeEq(std::size_t n) const
240*58b9f456SAndroid Build Coastguard Worker     {
241*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n == last_new_size;
242*58b9f456SAndroid Build Coastguard Worker     }
243*58b9f456SAndroid Build Coastguard Worker 
checkLastNewSizeNotEq(std::size_t n) const244*58b9f456SAndroid Build Coastguard Worker     bool checkLastNewSizeNotEq(std::size_t n) const
245*58b9f456SAndroid Build Coastguard Worker     {
246*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n != last_new_size;
247*58b9f456SAndroid Build Coastguard Worker     }
248*58b9f456SAndroid Build Coastguard Worker 
checkLastNewAlignEq(std::size_t n) const249*58b9f456SAndroid Build Coastguard Worker     bool checkLastNewAlignEq(std::size_t n) const
250*58b9f456SAndroid Build Coastguard Worker     {
251*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n == last_new_align;
252*58b9f456SAndroid Build Coastguard Worker     }
253*58b9f456SAndroid Build Coastguard Worker 
checkLastNewAlignNotEq(std::size_t n) const254*58b9f456SAndroid Build Coastguard Worker     bool checkLastNewAlignNotEq(std::size_t n) const
255*58b9f456SAndroid Build Coastguard Worker     {
256*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n != last_new_align;
257*58b9f456SAndroid Build Coastguard Worker     }
258*58b9f456SAndroid Build Coastguard Worker 
checkLastDeleteAlignEq(std::size_t n) const259*58b9f456SAndroid Build Coastguard Worker     bool checkLastDeleteAlignEq(std::size_t n) const
260*58b9f456SAndroid Build Coastguard Worker     {
261*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n == last_delete_align;
262*58b9f456SAndroid Build Coastguard Worker     }
263*58b9f456SAndroid Build Coastguard Worker 
checkLastDeleteAlignNotEq(std::size_t n) const264*58b9f456SAndroid Build Coastguard Worker     bool checkLastDeleteAlignNotEq(std::size_t n) const
265*58b9f456SAndroid Build Coastguard Worker     {
266*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n != last_delete_align;
267*58b9f456SAndroid Build Coastguard Worker     }
268*58b9f456SAndroid Build Coastguard Worker 
checkOutstandingArrayNewEq(int n) const269*58b9f456SAndroid Build Coastguard Worker     bool checkOutstandingArrayNewEq(int n) const
270*58b9f456SAndroid Build Coastguard Worker     {
271*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n == outstanding_array_new;
272*58b9f456SAndroid Build Coastguard Worker     }
273*58b9f456SAndroid Build Coastguard Worker 
checkOutstandingArrayNewNotEq(int n) const274*58b9f456SAndroid Build Coastguard Worker     bool checkOutstandingArrayNewNotEq(int n) const
275*58b9f456SAndroid Build Coastguard Worker     {
276*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n != outstanding_array_new;
277*58b9f456SAndroid Build Coastguard Worker     }
278*58b9f456SAndroid Build Coastguard Worker 
checkNewArrayCalledEq(int n) const279*58b9f456SAndroid Build Coastguard Worker     bool checkNewArrayCalledEq(int n) const
280*58b9f456SAndroid Build Coastguard Worker     {
281*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n == new_array_called;
282*58b9f456SAndroid Build Coastguard Worker     }
283*58b9f456SAndroid Build Coastguard Worker 
checkNewArrayCalledNotEq(int n) const284*58b9f456SAndroid Build Coastguard Worker     bool checkNewArrayCalledNotEq(int n) const
285*58b9f456SAndroid Build Coastguard Worker     {
286*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n != new_array_called;
287*58b9f456SAndroid Build Coastguard Worker     }
288*58b9f456SAndroid Build Coastguard Worker 
checkDeleteArrayCalledEq(int n) const289*58b9f456SAndroid Build Coastguard Worker     bool checkDeleteArrayCalledEq(int n) const
290*58b9f456SAndroid Build Coastguard Worker     {
291*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n == delete_array_called;
292*58b9f456SAndroid Build Coastguard Worker     }
293*58b9f456SAndroid Build Coastguard Worker 
checkDeleteArrayCalledNotEq(int n) const294*58b9f456SAndroid Build Coastguard Worker     bool checkDeleteArrayCalledNotEq(int n) const
295*58b9f456SAndroid Build Coastguard Worker     {
296*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n != delete_array_called;
297*58b9f456SAndroid Build Coastguard Worker     }
298*58b9f456SAndroid Build Coastguard Worker 
checkAlignedNewArrayCalledEq(int n) const299*58b9f456SAndroid Build Coastguard Worker     bool checkAlignedNewArrayCalledEq(int n) const
300*58b9f456SAndroid Build Coastguard Worker     {
301*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n == aligned_new_array_called;
302*58b9f456SAndroid Build Coastguard Worker     }
303*58b9f456SAndroid Build Coastguard Worker 
checkAlignedNewArrayCalledNotEq(int n) const304*58b9f456SAndroid Build Coastguard Worker     bool checkAlignedNewArrayCalledNotEq(int n) const
305*58b9f456SAndroid Build Coastguard Worker     {
306*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n != aligned_new_array_called;
307*58b9f456SAndroid Build Coastguard Worker     }
308*58b9f456SAndroid Build Coastguard Worker 
checkAlignedNewArrayCalledGreaterThan(int n) const309*58b9f456SAndroid Build Coastguard Worker     bool checkAlignedNewArrayCalledGreaterThan(int n) const
310*58b9f456SAndroid Build Coastguard Worker     {
311*58b9f456SAndroid Build Coastguard Worker         return disable_checking || aligned_new_array_called > n;
312*58b9f456SAndroid Build Coastguard Worker     }
313*58b9f456SAndroid Build Coastguard Worker 
checkAlignedDeleteArrayCalledEq(int n) const314*58b9f456SAndroid Build Coastguard Worker     bool checkAlignedDeleteArrayCalledEq(int n) const
315*58b9f456SAndroid Build Coastguard Worker     {
316*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n == aligned_delete_array_called;
317*58b9f456SAndroid Build Coastguard Worker     }
318*58b9f456SAndroid Build Coastguard Worker 
checkAlignedDeleteArrayCalledNotEq(int n) const319*58b9f456SAndroid Build Coastguard Worker     bool checkAlignedDeleteArrayCalledNotEq(int n) const
320*58b9f456SAndroid Build Coastguard Worker     {
321*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n != aligned_delete_array_called;
322*58b9f456SAndroid Build Coastguard Worker     }
323*58b9f456SAndroid Build Coastguard Worker 
checkLastNewArraySizeEq(std::size_t n) const324*58b9f456SAndroid Build Coastguard Worker     bool checkLastNewArraySizeEq(std::size_t n) const
325*58b9f456SAndroid Build Coastguard Worker     {
326*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n == last_new_array_size;
327*58b9f456SAndroid Build Coastguard Worker     }
328*58b9f456SAndroid Build Coastguard Worker 
checkLastNewArraySizeNotEq(std::size_t n) const329*58b9f456SAndroid Build Coastguard Worker     bool checkLastNewArraySizeNotEq(std::size_t n) const
330*58b9f456SAndroid Build Coastguard Worker     {
331*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n != last_new_array_size;
332*58b9f456SAndroid Build Coastguard Worker     }
333*58b9f456SAndroid Build Coastguard Worker 
checkLastNewArrayAlignEq(std::size_t n) const334*58b9f456SAndroid Build Coastguard Worker     bool checkLastNewArrayAlignEq(std::size_t n) const
335*58b9f456SAndroid Build Coastguard Worker     {
336*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n == last_new_array_align;
337*58b9f456SAndroid Build Coastguard Worker     }
338*58b9f456SAndroid Build Coastguard Worker 
checkLastNewArrayAlignNotEq(std::size_t n) const339*58b9f456SAndroid Build Coastguard Worker     bool checkLastNewArrayAlignNotEq(std::size_t n) const
340*58b9f456SAndroid Build Coastguard Worker     {
341*58b9f456SAndroid Build Coastguard Worker         return disable_checking || n != last_new_array_align;
342*58b9f456SAndroid Build Coastguard Worker     }
343*58b9f456SAndroid Build Coastguard Worker };
344*58b9f456SAndroid Build Coastguard Worker 
345*58b9f456SAndroid Build Coastguard Worker #ifdef DISABLE_NEW_COUNT
346*58b9f456SAndroid Build Coastguard Worker   const bool MemCounter::disable_checking = true;
347*58b9f456SAndroid Build Coastguard Worker #else
348*58b9f456SAndroid Build Coastguard Worker   const bool MemCounter::disable_checking = false;
349*58b9f456SAndroid Build Coastguard Worker #endif
350*58b9f456SAndroid Build Coastguard Worker 
getGlobalMemCounter()351*58b9f456SAndroid Build Coastguard Worker inline MemCounter* getGlobalMemCounter() {
352*58b9f456SAndroid Build Coastguard Worker   static MemCounter counter((MemCounter::MemCounterCtorArg_()));
353*58b9f456SAndroid Build Coastguard Worker   return &counter;
354*58b9f456SAndroid Build Coastguard Worker }
355*58b9f456SAndroid Build Coastguard Worker 
356*58b9f456SAndroid Build Coastguard Worker MemCounter &globalMemCounter = *getGlobalMemCounter();
357*58b9f456SAndroid Build Coastguard Worker 
358*58b9f456SAndroid Build Coastguard Worker #ifndef DISABLE_NEW_COUNT
operator new(std::size_t s)359*58b9f456SAndroid Build Coastguard Worker void* operator new(std::size_t s) TEST_THROW_SPEC(std::bad_alloc)
360*58b9f456SAndroid Build Coastguard Worker {
361*58b9f456SAndroid Build Coastguard Worker     getGlobalMemCounter()->newCalled(s);
362*58b9f456SAndroid Build Coastguard Worker     void* ret = std::malloc(s);
363*58b9f456SAndroid Build Coastguard Worker     if (ret == nullptr)
364*58b9f456SAndroid Build Coastguard Worker         detail::throw_bad_alloc_helper();
365*58b9f456SAndroid Build Coastguard Worker     return ret;
366*58b9f456SAndroid Build Coastguard Worker }
367*58b9f456SAndroid Build Coastguard Worker 
operator delete(void * p)368*58b9f456SAndroid Build Coastguard Worker void  operator delete(void* p) TEST_NOEXCEPT
369*58b9f456SAndroid Build Coastguard Worker {
370*58b9f456SAndroid Build Coastguard Worker     getGlobalMemCounter()->deleteCalled(p);
371*58b9f456SAndroid Build Coastguard Worker     std::free(p);
372*58b9f456SAndroid Build Coastguard Worker }
373*58b9f456SAndroid Build Coastguard Worker 
operator new[](std::size_t s)374*58b9f456SAndroid Build Coastguard Worker void* operator new[](std::size_t s) TEST_THROW_SPEC(std::bad_alloc)
375*58b9f456SAndroid Build Coastguard Worker {
376*58b9f456SAndroid Build Coastguard Worker     getGlobalMemCounter()->newArrayCalled(s);
377*58b9f456SAndroid Build Coastguard Worker     return operator new(s);
378*58b9f456SAndroid Build Coastguard Worker }
379*58b9f456SAndroid Build Coastguard Worker 
operator delete[](void * p)380*58b9f456SAndroid Build Coastguard Worker void operator delete[](void* p) TEST_NOEXCEPT
381*58b9f456SAndroid Build Coastguard Worker {
382*58b9f456SAndroid Build Coastguard Worker     getGlobalMemCounter()->deleteArrayCalled(p);
383*58b9f456SAndroid Build Coastguard Worker     operator delete(p);
384*58b9f456SAndroid Build Coastguard Worker }
385*58b9f456SAndroid Build Coastguard Worker 
386*58b9f456SAndroid Build Coastguard Worker #ifndef TEST_HAS_NO_ALIGNED_ALLOCATION
387*58b9f456SAndroid Build Coastguard Worker #if defined(_LIBCPP_MSVCRT_LIKE) || \
388*58b9f456SAndroid Build Coastguard Worker   (!defined(_LIBCPP_VERSION) && defined(_WIN32))
389*58b9f456SAndroid Build Coastguard Worker #define USE_ALIGNED_ALLOC
390*58b9f456SAndroid Build Coastguard Worker #endif
391*58b9f456SAndroid Build Coastguard Worker 
operator new(std::size_t s,std::align_val_t av)392*58b9f456SAndroid Build Coastguard Worker void* operator new(std::size_t s, std::align_val_t av) TEST_THROW_SPEC(std::bad_alloc) {
393*58b9f456SAndroid Build Coastguard Worker   const std::size_t a = static_cast<std::size_t>(av);
394*58b9f456SAndroid Build Coastguard Worker   getGlobalMemCounter()->alignedNewCalled(s, a);
395*58b9f456SAndroid Build Coastguard Worker   void *ret;
396*58b9f456SAndroid Build Coastguard Worker #ifdef USE_ALIGNED_ALLOC
397*58b9f456SAndroid Build Coastguard Worker   ret = _aligned_malloc(s, a);
398*58b9f456SAndroid Build Coastguard Worker #else
399*58b9f456SAndroid Build Coastguard Worker   posix_memalign(&ret, a, s);
400*58b9f456SAndroid Build Coastguard Worker #endif
401*58b9f456SAndroid Build Coastguard Worker   if (ret == nullptr)
402*58b9f456SAndroid Build Coastguard Worker     detail::throw_bad_alloc_helper();
403*58b9f456SAndroid Build Coastguard Worker   return ret;
404*58b9f456SAndroid Build Coastguard Worker }
405*58b9f456SAndroid Build Coastguard Worker 
operator delete(void * p,std::align_val_t av)406*58b9f456SAndroid Build Coastguard Worker void operator delete(void *p, std::align_val_t av) TEST_NOEXCEPT {
407*58b9f456SAndroid Build Coastguard Worker   const std::size_t a = static_cast<std::size_t>(av);
408*58b9f456SAndroid Build Coastguard Worker   getGlobalMemCounter()->alignedDeleteCalled(p, a);
409*58b9f456SAndroid Build Coastguard Worker   if (p) {
410*58b9f456SAndroid Build Coastguard Worker #ifdef USE_ALIGNED_ALLOC
411*58b9f456SAndroid Build Coastguard Worker     ::_aligned_free(p);
412*58b9f456SAndroid Build Coastguard Worker #else
413*58b9f456SAndroid Build Coastguard Worker     ::free(p);
414*58b9f456SAndroid Build Coastguard Worker #endif
415*58b9f456SAndroid Build Coastguard Worker   }
416*58b9f456SAndroid Build Coastguard Worker }
417*58b9f456SAndroid Build Coastguard Worker 
operator new[](std::size_t s,std::align_val_t av)418*58b9f456SAndroid Build Coastguard Worker void* operator new[](std::size_t s, std::align_val_t av) TEST_THROW_SPEC(std::bad_alloc) {
419*58b9f456SAndroid Build Coastguard Worker   const std::size_t a = static_cast<std::size_t>(av);
420*58b9f456SAndroid Build Coastguard Worker   getGlobalMemCounter()->alignedNewArrayCalled(s, a);
421*58b9f456SAndroid Build Coastguard Worker   return operator new(s, av);
422*58b9f456SAndroid Build Coastguard Worker }
423*58b9f456SAndroid Build Coastguard Worker 
operator delete[](void * p,std::align_val_t av)424*58b9f456SAndroid Build Coastguard Worker void operator delete[](void *p, std::align_val_t av) TEST_NOEXCEPT {
425*58b9f456SAndroid Build Coastguard Worker   const std::size_t a = static_cast<std::size_t>(av);
426*58b9f456SAndroid Build Coastguard Worker   getGlobalMemCounter()->alignedDeleteArrayCalled(p, a);
427*58b9f456SAndroid Build Coastguard Worker   return operator delete(p, av);
428*58b9f456SAndroid Build Coastguard Worker }
429*58b9f456SAndroid Build Coastguard Worker 
430*58b9f456SAndroid Build Coastguard Worker #endif // TEST_HAS_NO_ALIGNED_ALLOCATION
431*58b9f456SAndroid Build Coastguard Worker 
432*58b9f456SAndroid Build Coastguard Worker #endif // DISABLE_NEW_COUNT
433*58b9f456SAndroid Build Coastguard Worker 
434*58b9f456SAndroid Build Coastguard Worker struct DisableAllocationGuard {
DisableAllocationGuardDisableAllocationGuard435*58b9f456SAndroid Build Coastguard Worker     explicit DisableAllocationGuard(bool disable = true) : m_disabled(disable)
436*58b9f456SAndroid Build Coastguard Worker     {
437*58b9f456SAndroid Build Coastguard Worker         // Don't re-disable if already disabled.
438*58b9f456SAndroid Build Coastguard Worker         if (globalMemCounter.disable_allocations == true) m_disabled = false;
439*58b9f456SAndroid Build Coastguard Worker         if (m_disabled) globalMemCounter.disableAllocations();
440*58b9f456SAndroid Build Coastguard Worker     }
441*58b9f456SAndroid Build Coastguard Worker 
releaseDisableAllocationGuard442*58b9f456SAndroid Build Coastguard Worker     void release() {
443*58b9f456SAndroid Build Coastguard Worker         if (m_disabled) globalMemCounter.enableAllocations();
444*58b9f456SAndroid Build Coastguard Worker         m_disabled = false;
445*58b9f456SAndroid Build Coastguard Worker     }
446*58b9f456SAndroid Build Coastguard Worker 
~DisableAllocationGuardDisableAllocationGuard447*58b9f456SAndroid Build Coastguard Worker     ~DisableAllocationGuard() {
448*58b9f456SAndroid Build Coastguard Worker         release();
449*58b9f456SAndroid Build Coastguard Worker     }
450*58b9f456SAndroid Build Coastguard Worker 
451*58b9f456SAndroid Build Coastguard Worker private:
452*58b9f456SAndroid Build Coastguard Worker     bool m_disabled;
453*58b9f456SAndroid Build Coastguard Worker 
454*58b9f456SAndroid Build Coastguard Worker     DisableAllocationGuard(DisableAllocationGuard const&);
455*58b9f456SAndroid Build Coastguard Worker     DisableAllocationGuard& operator=(DisableAllocationGuard const&);
456*58b9f456SAndroid Build Coastguard Worker };
457*58b9f456SAndroid Build Coastguard Worker 
458*58b9f456SAndroid Build Coastguard Worker struct RequireAllocationGuard {
RequireAllocationGuardRequireAllocationGuard459*58b9f456SAndroid Build Coastguard Worker     explicit RequireAllocationGuard(std::size_t RequireAtLeast = 1)
460*58b9f456SAndroid Build Coastguard Worker             : m_req_alloc(RequireAtLeast),
461*58b9f456SAndroid Build Coastguard Worker               m_new_count_on_init(globalMemCounter.new_called),
462*58b9f456SAndroid Build Coastguard Worker               m_outstanding_new_on_init(globalMemCounter.outstanding_new),
463*58b9f456SAndroid Build Coastguard Worker               m_exactly(false)
464*58b9f456SAndroid Build Coastguard Worker     {
465*58b9f456SAndroid Build Coastguard Worker     }
466*58b9f456SAndroid Build Coastguard Worker 
requireAtLeastRequireAllocationGuard467*58b9f456SAndroid Build Coastguard Worker     void requireAtLeast(std::size_t N) { m_req_alloc = N; m_exactly = false; }
requireExactlyRequireAllocationGuard468*58b9f456SAndroid Build Coastguard Worker     void requireExactly(std::size_t N) { m_req_alloc = N; m_exactly = true; }
469*58b9f456SAndroid Build Coastguard Worker 
~RequireAllocationGuardRequireAllocationGuard470*58b9f456SAndroid Build Coastguard Worker     ~RequireAllocationGuard() {
471*58b9f456SAndroid Build Coastguard Worker         assert(globalMemCounter.checkOutstandingNewEq(static_cast<int>(m_outstanding_new_on_init)));
472*58b9f456SAndroid Build Coastguard Worker         std::size_t Expect = m_new_count_on_init + m_req_alloc;
473*58b9f456SAndroid Build Coastguard Worker         assert(globalMemCounter.checkNewCalledEq(static_cast<int>(Expect)) ||
474*58b9f456SAndroid Build Coastguard Worker                (!m_exactly && globalMemCounter.checkNewCalledGreaterThan(static_cast<int>(Expect))));
475*58b9f456SAndroid Build Coastguard Worker     }
476*58b9f456SAndroid Build Coastguard Worker 
477*58b9f456SAndroid Build Coastguard Worker private:
478*58b9f456SAndroid Build Coastguard Worker     std::size_t m_req_alloc;
479*58b9f456SAndroid Build Coastguard Worker     const std::size_t m_new_count_on_init;
480*58b9f456SAndroid Build Coastguard Worker     const std::size_t m_outstanding_new_on_init;
481*58b9f456SAndroid Build Coastguard Worker     bool m_exactly;
482*58b9f456SAndroid Build Coastguard Worker     RequireAllocationGuard(RequireAllocationGuard const&);
483*58b9f456SAndroid Build Coastguard Worker     RequireAllocationGuard& operator=(RequireAllocationGuard const&);
484*58b9f456SAndroid Build Coastguard Worker };
485*58b9f456SAndroid Build Coastguard Worker 
486*58b9f456SAndroid Build Coastguard Worker #endif /* COUNT_NEW_HPP */
487