• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ivmai / bdwgc / 1486

20 Apr 2023 10:28AM UTC coverage: 76.615% (+0.1%) from 76.519%
1486

push

travis-ci-com

ivmai
Provide global non-throwing operator new/delete in gccpp library

Note: this might require define GC_INCLUDE_NEW by client before
include gc_cpp.h on Windows hosts (to have nothrow_t declared before
the global inline operator new and delete are defined).

* gc_cpp.cc [(!_MSC_VER && !__DMC__ || GC_NO_INLINE_STD_NEW)
&& !GC_INLINE_STD_NEW && GC_OPERATOR_NEW_NOTHROW] (operator new,
operator delete): Define with nothrow_t argument.
* gc_cpp.cc [(!_MSC_VER && !__DMC__ || GC_NO_INLINE_STD_NEW)
&& !GC_INLINE_STD_NEW && GC_OPERATOR_NEW_ARRAY && !CPPCHECK
&& GC_OPERATOR_NEW_NOTHROW] (operator new[], operator delete[]):
Likewise.
* include/gc/gc_cpp.h [GC_INLINE_STD_NEW && GC_OPERATOR_NEW_ARRAY
&& GC_OPERATOR_NEW_NOTHROW] (operator new[], operator delete[]):
Likewise.
* include/gc/gc_cpp.h [GC_INLINE_STD_NEW && GC_OPERATOR_NEW_NOTHROW]
(operator new, operator delete): Likewise.
* include/gc/gc_cpp.h [!GC_OPERATOR_NEW_NOTHROW
&& !GC_NO_OPERATOR_NEW_NOTHROW && (GC_INCLUDE_NEW
&& (__cplusplus>=201103L || _MSVC_LANG>=201103L)
|| __NOTHROW_T_DEFINED)] (GC_OPERATOR_NEW_NOTHROW): Define macro;
add comment.
* include/gc/gc_cpp.h [!GC_INLINE_STD_NEW && GC_NO_INLINE_STD_NEW
&& _MSC_VER && GC_OPERATOR_NEW_ARRAY && GC_OPERATOR_NEW_NOTHROW]
(operator new[], operator delete[]): Add prototype with nothrow_t
argument (with commented out GC_ATTR_MALLOC).
* include/gc/gc_cpp.h [!GC_INLINE_STD_NEW && GC_NO_INLINE_STD_NEW
&& _MSC_VER && GC_OPERATOR_NEW_NOTHROW] (operator new,
operator delete): Likewise.

7781 of 10156 relevant lines covered (76.61%)

8930874.76 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.62
/include/gc/gc_cpp.h
1
/*
2
 * Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
3
 *
4
 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
5
 * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
6
 *
7
 * Permission is hereby granted to use or copy this program for any
8
 * purpose, provided the above notices are retained on all copies.
9
 * Permission to modify the code and to distribute modified code is
10
 * granted, provided the above notices are retained, and a notice that
11
 * the code was modified is included with the above copyright notice.
12
 */
13

14
#ifndef GC_CPP_H
15
#define GC_CPP_H
16

17
/****************************************************************************
18
C++ Interface to the Boehm Collector
19

20
    John R. Ellis and Jesse Hull
21

22
This interface provides access to the Boehm collector.  It provides
23
basic facilities similar to those described in "Safe, Efficient
24
Garbage Collection for C++", by John R. Ellis and David L. Detlefs
25
(ftp://ftp.parc.xerox.com/pub/ellis/gc).
26

27
All heap-allocated objects are either "collectible" or
28
"uncollectible".  Programs must explicitly delete uncollectible
29
objects, whereas the garbage collector will automatically delete
30
collectible objects when it discovers them to be inaccessible.
31
Collectible objects may freely point at uncollectible objects and vice
32
versa.
33

34
Objects allocated with the built-in "::operator new" are uncollectible.
35

36
Objects derived from class "gc" are collectible.  For example:
37

38
    class A: public gc {...};
39
    A* a = new A;       // a is collectible.
40

41
Collectible instances of non-class types can be allocated using the GC
42
(or UseGC) placement:
43

44
    typedef int A[ 10 ];
45
    A* a = new (GC) A;
46

47
Uncollectible instances of classes derived from "gc" can be allocated
48
using the NoGC placement:
49

50
    class A: public gc {...};
51
    A* a = new (NoGC) A;   // a is uncollectible.
52

53
The new(PointerFreeGC) syntax allows the allocation of collectible
54
objects that are not scanned by the collector.  This useful if you
55
are allocating compressed data, bitmaps, or network packets.  (In
56
the latter case, it may remove danger of unfriendly network packets
57
intentionally containing values that cause spurious memory retention.)
58

59
Both uncollectible and collectible objects can be explicitly deleted
60
with "delete", which invokes an object's destructors and frees its
61
storage immediately.
62

63
A collectible object may have a clean-up function, which will be
64
invoked when the collector discovers the object to be inaccessible.
65
An object derived from "gc_cleanup" or containing a member derived
66
from "gc_cleanup" has a default clean-up function that invokes the
67
object's destructors.  Explicit clean-up functions may be specified as
68
an additional placement argument:
69

70
    A* a = ::new (GC, MyCleanup) A;
71

72
An object is considered "accessible" by the collector if it can be
73
reached by a path of pointers from static variables, automatic
74
variables of active functions, or from some object with clean-up
75
enabled; pointers from an object to itself are ignored.
76

77
Thus, if objects A and B both have clean-up functions, and A points at
78
B, B is considered accessible.  After A's clean-up is invoked and its
79
storage released, B will then become inaccessible and will have its
80
clean-up invoked.  If A points at B and B points to A, forming a
81
cycle, then that's considered a storage leak, and neither will be
82
collectible.  See the interface gc.h for low-level facilities for
83
handling such cycles of objects with clean-up.
84

85
The collector cannot guarantee that it will find all inaccessible
86
objects.  In practice, it finds almost all of them.
87

88
Cautions:
89

90
1. Be sure the collector is compiled with the C++ support
91
(e.g. --enable-cplusplus option is passed to make).
92

93
2. If the compiler does not support "operator new[]", beware that an
94
array of type T, where T is derived from "gc", may or may not be
95
allocated as a collectible object (it depends on the compiler).  Use
96
the explicit GC placement to make the array collectible.  For example:
97

98
    class A: public gc {...};
99
    A* a1 = new A[ 10 ];        // collectible or uncollectible?
100
    A* a2 = new (GC) A[ 10 ];   // collectible.
101

102
3. The destructors of collectible arrays of objects derived from
103
"gc_cleanup" will not be invoked properly.  For example:
104

105
    class A: public gc_cleanup {...};
106
    A* a = new (GC) A[ 10 ];    // destructors not invoked correctly
107

108
Typically, only the destructor for the first element of the array will
109
be invoked when the array is garbage-collected.  To get all the
110
destructors of any array executed, you must supply an explicit
111
clean-up function:
112

113
    A* a = new (GC, MyCleanUp) A[ 10 ];
114

115
(Implementing clean-up of arrays correctly, portably, and in a way
116
that preserves the correct exception semantics requires a language
117
extension, e.g. the "gc" keyword.)
118

119
4. GC name conflicts:
120

121
Many other systems seem to use the identifier "GC" as an abbreviation
122
for "Graphics Context".  Thus, GC placement has been replaced
123
by UseGC.  GC is an alias for UseGC, unless GC_NAME_CONFLICT is defined.
124

125
****************************************************************************/
126

127
#include "gc.h"
128

129
#ifdef GC_INCLUDE_NEW
130
# include <new> // for std, bad_alloc
131
#endif
132

133
#if defined(GC_INCLUDE_NEW) && (__cplusplus >= 201103L)
134
# define GC_PTRDIFF_T std::ptrdiff_t
135
# define GC_SIZE_T std::size_t
136
#else
137
# define GC_PTRDIFF_T ptrdiff_t
138
# define GC_SIZE_T size_t
139
#endif
140

141
#ifdef GC_NAMESPACE
142
# define GC_NS_QUALIFY(T) boehmgc::T
143
#else
144
# define GC_NS_QUALIFY(T) T
145
#endif
146

147
#ifndef THINK_CPLUS
148
# define GC_cdecl GC_CALLBACK
149
#else
150
# define GC_cdecl _cdecl
151
#endif
152

153
#if !defined(GC_NO_OPERATOR_NEW_ARRAY) \
154
    && !defined(_ENABLE_ARRAYNEW) /* Digimars */ \
155
    && (defined(__BORLANDC__) && (__BORLANDC__ < 0x450) \
156
        || (defined(__GNUC__) && !GC_GNUC_PREREQ(2, 6)) \
157
        || (defined(_MSC_VER) && _MSC_VER <= 1020) \
158
        || (defined(__WATCOMC__) && __WATCOMC__ < 1050))
159
# define GC_NO_OPERATOR_NEW_ARRAY
160
#endif
161

162
#if !defined(GC_NO_OPERATOR_NEW_ARRAY) && !defined(GC_OPERATOR_NEW_ARRAY)
163
# define GC_OPERATOR_NEW_ARRAY
164
#endif
165

166
#if !defined(GC_NO_INLINE_STD_NEW) && !defined(GC_INLINE_STD_NEW) \
167
    && (defined(_MSC_VER) || defined(__DMC__) \
168
        || ((defined(__BORLANDC__) || defined(__CYGWIN__) \
169
             || defined(__CYGWIN32__) || defined(__MINGW32__) \
170
             || defined(__WATCOMC__)) \
171
            && !defined(GC_BUILD) && !defined(GC_NOT_DLL)))
172
  // Inlining done to avoid mix up of new and delete operators by VC++ 9
173
  // (due to arbitrary ordering during linking).
174
# define GC_INLINE_STD_NEW
175
#endif
176

177
#if (!defined(__BORLANDC__) || __BORLANDC__ > 0x0620) \
178
    && !defined(__sgi) && !defined(__WATCOMC__) \
179
    && (!defined(_MSC_VER) || _MSC_VER > 1020)
180
# define GC_PLACEMENT_DELETE
181
#endif
182

183
#if !defined(GC_OPERATOR_SIZED_DELETE) \
184
    && !defined(GC_NO_OPERATOR_SIZED_DELETE) \
185
    && (__cplusplus >= 201402L || _MSVC_LANG >= 201402L) // C++14
186
# define GC_OPERATOR_SIZED_DELETE
187
#endif
188

189
#if !defined(GC_OPERATOR_NEW_NOTHROW) \
190
    && !defined(GC_NO_OPERATOR_NEW_NOTHROW) \
191
    && ((defined(GC_INCLUDE_NEW) \
192
         && (__cplusplus >= 201103L || _MSVC_LANG >= 201103L)) \
193
        || defined(__NOTHROW_T_DEFINED))
194
  // Note: this might require defining GC_INCLUDE_NEW by client
195
  // before include gc_cpp.h (on Windows).
196
# define GC_OPERATOR_NEW_NOTHROW
197
#endif
198

199
#if !defined(GC_NEW_DELETE_THROW_NOT_NEEDED) \
200
    && !defined(GC_NEW_DELETE_NEED_THROW) && GC_GNUC_PREREQ(4, 2) \
201
    && (__cplusplus < 201103L || defined(__clang__))
202
# define GC_NEW_DELETE_NEED_THROW
203
#endif
204

205
#ifndef GC_NEW_DELETE_NEED_THROW
206
# define GC_DECL_NEW_THROW /* empty */
207
#elif __cplusplus >= 201703L || _MSVC_LANG >= 201703L
208
  // The "dynamic exception" syntax had been deprecated in C++11
209
  // and was removed in C++17.
210
# define GC_DECL_NEW_THROW noexcept(false)
211
#elif defined(GC_INCLUDE_NEW)
212
# define GC_DECL_NEW_THROW throw(std::bad_alloc)
213
#else
214
# define GC_DECL_NEW_THROW /* empty (as bad_alloc might be undeclared) */
215
#endif
216

217
#if defined(GC_NEW_ABORTS_ON_OOM) || defined(_LIBCPP_NO_EXCEPTIONS)
218
# define GC_OP_NEW_OOM_CHECK(obj) \
219
                do { if (!(obj)) GC_abort_on_oom(); } while (0)
220
#elif defined(GC_INCLUDE_NEW)
221
# define GC_OP_NEW_OOM_CHECK(obj) if (obj) {} else throw std::bad_alloc()
222
#else
223
  // "new" header is not included, so bad_alloc cannot be thrown directly.
224
  GC_API void GC_CALL GC_throw_bad_alloc();
225
# define GC_OP_NEW_OOM_CHECK(obj) if (obj) {} else GC_throw_bad_alloc()
226
#endif // !GC_NEW_ABORTS_ON_OOM && !GC_INCLUDE_NEW
227

228
#ifdef GC_NAMESPACE
229
namespace boehmgc
230
{
231
#endif
232

233
enum GCPlacement
234
{
235
  UseGC,
236
# ifndef GC_NAME_CONFLICT
237
    GC = UseGC,
238
# endif
239
  NoGC,
240
  PointerFreeGC
241
# ifdef GC_ATOMIC_UNCOLLECTABLE
242
    , PointerFreeNoGC
243
# endif
244
};
245

246
/**
247
 * Instances of classes derived from gc will be allocated in the collected
248
 * heap by default, unless an explicit NoGC placement is specified.
249
 */
250
class gc
28,252,000✔
251
{
252
public:
253
  inline void* operator new(GC_SIZE_T);
254
  inline void* operator new(GC_SIZE_T, GCPlacement);
255
  inline void* operator new(GC_SIZE_T, void*) GC_NOEXCEPT;
256
    // Must be redefined here, since the other overloadings hide
257
    // the global definition.
258
  inline void operator delete(void*) GC_NOEXCEPT;
259
# ifdef GC_OPERATOR_SIZED_DELETE
260
    inline void operator delete(void*, GC_SIZE_T) GC_NOEXCEPT;
261
# endif
262

263
# ifdef GC_PLACEMENT_DELETE
264
    inline void operator delete(void*, GCPlacement) GC_NOEXCEPT;
265
      // Called if construction fails.
266
    inline void operator delete(void*, void*) GC_NOEXCEPT;
267
# endif // GC_PLACEMENT_DELETE
268

269
# ifdef GC_OPERATOR_NEW_ARRAY
270
    inline void* operator new[](GC_SIZE_T);
271
    inline void* operator new[](GC_SIZE_T, GCPlacement);
272
    inline void* operator new[](GC_SIZE_T, void*) GC_NOEXCEPT;
273
    inline void operator delete[](void*) GC_NOEXCEPT;
274
#   ifdef GC_OPERATOR_SIZED_DELETE
275
      inline void operator delete[](void*, GC_SIZE_T) GC_NOEXCEPT;
276
#   endif
277
#   ifdef GC_PLACEMENT_DELETE
278
      inline void operator delete[](void*, GCPlacement) GC_NOEXCEPT;
279
      inline void operator delete[](void*, void*) GC_NOEXCEPT;
280
#   endif
281
# endif // GC_OPERATOR_NEW_ARRAY
282
};
283

284
/**
285
 * Instances of classes derived from gc_cleanup will be allocated
286
 * in the collected heap by default.  When the collector discovers
287
 * an inaccessible object derived from gc_cleanup or containing
288
 * a member derived from gc_cleanup, its destructors will be invoked.
289
 */
290
class gc_cleanup: virtual public gc
291
{
292
public:
293
  inline gc_cleanup();
294
  inline virtual ~gc_cleanup();
295

296
private:
297
  inline static void GC_cdecl cleanup(void* obj, void* clientData);
298
};
299

300
extern "C" {
301
  typedef void (GC_CALLBACK * GCCleanUpFunc)(void* obj, void* clientData);
302
}
303

304
#ifdef GC_NAMESPACE
305
}
306
#endif
307

308
#ifdef _MSC_VER
309
  // Disable warning that "no matching operator delete found; memory will
310
  // not be freed if initialization throws an exception"
311
# pragma warning(disable:4291)
312
  // TODO: "non-member operator new or delete may not be declared inline"
313
  // warning is disabled for now.
314
# pragma warning(disable:4595)
315
#endif
316

317
inline void* operator new(GC_SIZE_T, GC_NS_QUALIFY(GCPlacement),
318
                          GC_NS_QUALIFY(GCCleanUpFunc) = 0,
319
                          void* /* clientData */ = 0);
320
    // Allocates a collectible or uncollectible object, according to the
321
    // value of gcp.
322
    //
323
    // For collectible objects, if cleanup is non-null, then when the
324
    // allocated object obj becomes inaccessible, the collector will
325
    // invoke cleanup(obj,clientData) but will not invoke the object's
326
    // destructors.  It is an error to explicitly delete an object
327
    // allocated with a non-null cleanup.
328
    //
329
    // It is an error to specify a non-null cleanup with NoGC or for
330
    // classes derived from gc_cleanup or containing members derived
331
    // from gc_cleanup.
332

333
#ifdef GC_PLACEMENT_DELETE
334
  inline void operator delete(void*, GC_NS_QUALIFY(GCPlacement),
335
                              GC_NS_QUALIFY(GCCleanUpFunc),
336
                              void*) GC_NOEXCEPT;
337
#endif
338

339
#ifdef GC_INLINE_STD_NEW
340

341
# ifdef GC_OPERATOR_NEW_ARRAY
342
    inline void* operator new[](GC_SIZE_T size) GC_DECL_NEW_THROW
343
    {
344
      void* obj = GC_MALLOC_UNCOLLECTABLE(size);
345
      GC_OP_NEW_OOM_CHECK(obj);
346
      return obj;
347
    }
348

349
    inline void operator delete[](void* obj) GC_NOEXCEPT
350
    {
351
      GC_FREE(obj);
352
    }
353

354
#   ifdef GC_OPERATOR_NEW_NOTHROW
355
      inline /* GC_ATTR_MALLOC */ void* operator new[](GC_SIZE_T size,
356
                                            const std::nothrow_t&) GC_NOEXCEPT
357
      {
358
        return GC_MALLOC_UNCOLLECTABLE(size);
359
      }
360

361
      inline void operator delete[](void* obj,
362
                                    const std::nothrow_t&) GC_NOEXCEPT
363
      {
364
        GC_FREE(obj);
365
      }
366
#   endif // GC_OPERATOR_NEW_NOTHROW
367
# endif // GC_OPERATOR_NEW_ARRAY
368

369
  inline void* operator new(GC_SIZE_T size) GC_DECL_NEW_THROW
370
  {
371
    void* obj = GC_MALLOC_UNCOLLECTABLE(size);
372
    GC_OP_NEW_OOM_CHECK(obj);
373
    return obj;
374
  }
375

376
  inline void operator delete(void* obj) GC_NOEXCEPT
377
  {
378
    GC_FREE(obj);
379
  }
380

381
# ifdef GC_OPERATOR_NEW_NOTHROW
382
    inline /* GC_ATTR_MALLOC */ void* operator new(GC_SIZE_T size,
383
                                        const std::nothrow_t&) GC_NOEXCEPT
384
    {
385
      return GC_MALLOC_UNCOLLECTABLE(size);
386
    }
387

388
    inline void operator delete(void* obj, const std::nothrow_t&) GC_NOEXCEPT
389
    {
390
      GC_FREE(obj);
391
    }
392
# endif // GC_OPERATOR_NEW_NOTHROW
393

394
# ifdef GC_OPERATOR_SIZED_DELETE
395
    inline void operator delete(void* obj, GC_SIZE_T) GC_NOEXCEPT
396
    {
397
      GC_FREE(obj);
398
    }
399

400
#   ifdef GC_OPERATOR_NEW_ARRAY
401
      inline void operator delete[](void* obj, GC_SIZE_T) GC_NOEXCEPT
402
      {
403
        GC_FREE(obj);
404
      }
405
#   endif
406
# endif // GC_OPERATOR_SIZED_DELETE
407

408
# ifdef _MSC_VER
409
    // This new operator is used by VC++ in case of Debug builds.
410
    inline void* operator new(GC_SIZE_T size, int /* nBlockUse */,
411
                              const char* szFileName, int nLine)
412
    {
413
#     ifdef GC_DEBUG
414
        void* obj = GC_debug_malloc_uncollectable(size, szFileName, nLine);
415
#     else
416
        void* obj = GC_MALLOC_UNCOLLECTABLE(size);
417
        (void)szFileName; (void)nLine;
418
#     endif
419
      GC_OP_NEW_OOM_CHECK(obj);
420
      return obj;
421
    }
422

423
#   ifdef GC_OPERATOR_NEW_ARRAY
424
      // This new operator is used by VC++ 7+ in Debug builds.
425
      inline void* operator new[](GC_SIZE_T size, int nBlockUse,
426
                                  const char* szFileName, int nLine)
427
      {
428
        return operator new(size, nBlockUse, szFileName, nLine);
429
      }
430
#   endif
431
# endif // _MSC_VER
432

433
#elif defined(GC_NO_INLINE_STD_NEW) && defined(_MSC_VER)
434

435
  // The following ensures that the system default operator new[] does not
436
  // get undefined, which is what seems to happen on VC++ 6 for some reason
437
  // if we define a multi-argument operator new[].
438
  // There seems to be no way to redirect new in this environment without
439
  // including this everywhere.
440
# ifdef GC_OPERATOR_NEW_ARRAY
441
    void* operator new[](GC_SIZE_T) GC_DECL_NEW_THROW;
442
    void operator delete[](void*) GC_NOEXCEPT;
443
#   ifdef GC_OPERATOR_NEW_NOTHROW
444
      /* GC_ATTR_MALLOC */ void* operator new[](GC_SIZE_T,
445
                                    const std::nothrow_t&) GC_NOEXCEPT;
446
      void operator delete[](void*, const std::nothrow_t&) GC_NOEXCEPT;
447
#   endif
448
#   ifdef GC_OPERATOR_SIZED_DELETE
449
      void operator delete[](void*, GC_SIZE_T) GC_NOEXCEPT;
450
#   endif
451

452
    void* operator new[](GC_SIZE_T, int /* nBlockUse */,
453
                         const char* /* szFileName */, int /* nLine */);
454
# endif // GC_OPERATOR_NEW_ARRAY
455

456
  void* operator new(GC_SIZE_T) GC_DECL_NEW_THROW;
457
  void operator delete(void*) GC_NOEXCEPT;
458
# ifdef GC_OPERATOR_NEW_NOTHROW
459
    /* GC_ATTR_MALLOC */ void* operator new(GC_SIZE_T,
460
                                    const std::nothrow_t&) GC_NOEXCEPT;
461
    void operator delete(void*, const std::nothrow_t&) GC_NOEXCEPT;
462
# endif
463
# ifdef GC_OPERATOR_SIZED_DELETE
464
    void operator delete(void*, GC_SIZE_T) GC_NOEXCEPT;
465
# endif
466

467
  void* operator new(GC_SIZE_T, int /* nBlockUse */,
468
                     const char* /* szFileName */, int /* nLine */);
469

470
#endif // GC_NO_INLINE_STD_NEW && _MSC_VER
471

472
#ifdef GC_OPERATOR_NEW_ARRAY
473
  // The operator new for arrays, identical to the above.
474
  inline void* operator new[](GC_SIZE_T, GC_NS_QUALIFY(GCPlacement),
475
                              GC_NS_QUALIFY(GCCleanUpFunc) = 0,
476
                              void* /* clientData */ = 0);
477
#endif // GC_OPERATOR_NEW_ARRAY
478

479
// Inline implementation.
480

481
#ifdef GC_NAMESPACE
482
namespace boehmgc
483
{
484
#endif
485

486
inline void* gc::operator new(GC_SIZE_T size)
14,196,000✔
487
{
488
  void* obj = GC_MALLOC(size);
14,196,000✔
489
  GC_OP_NEW_OOM_CHECK(obj);
14,196,000✔
490
  return obj;
14,196,000✔
491
}
492

493
inline void* gc::operator new(GC_SIZE_T size, GCPlacement gcp)
14,014,000✔
494
{
495
  void* obj;
496
  switch (gcp) {
14,014,000✔
497
  case UseGC:
498
    obj = GC_MALLOC(size);
14,000,000✔
499
    break;
14,000,000✔
500
  case PointerFreeGC:
501
    obj = GC_MALLOC_ATOMIC(size);
×
502
    break;
×
503
# ifdef GC_ATOMIC_UNCOLLECTABLE
504
    case PointerFreeNoGC:
505
      obj = GC_MALLOC_ATOMIC_UNCOLLECTABLE(size);
×
506
      break;
×
507
# endif
508
  case NoGC:
509
  default:
510
    obj = GC_MALLOC_UNCOLLECTABLE(size);
14,000✔
511
  }
512
  GC_OP_NEW_OOM_CHECK(obj);
14,014,000✔
513
  return obj;
14,014,000✔
514
}
515

516
inline void* gc::operator new(GC_SIZE_T, void* p) GC_NOEXCEPT
517
{
518
  return p;
519
}
520

521
inline void gc::operator delete(void* obj) GC_NOEXCEPT
1,415,400✔
522
{
523
  GC_FREE(obj);
1,415,400✔
524
}
1,415,400✔
525

526
#ifdef GC_OPERATOR_SIZED_DELETE
527
  inline void gc::operator delete(void* obj, GC_SIZE_T) GC_NOEXCEPT
528
  {
529
    GC_FREE(obj);
530
  }
531
#endif
532

533
#ifdef GC_PLACEMENT_DELETE
534
  inline void gc::operator delete(void*, void*) GC_NOEXCEPT {}
535

536
  inline void gc::operator delete(void* obj, GCPlacement) GC_NOEXCEPT
537
  {
538
    GC_FREE(obj);
539
  }
540
#endif // GC_PLACEMENT_DELETE
541

542
#ifdef GC_OPERATOR_NEW_ARRAY
543
  inline void* gc::operator new[](GC_SIZE_T size)
544
  {
545
    return gc::operator new(size);
546
  }
547

548
  inline void* gc::operator new[](GC_SIZE_T size, GCPlacement gcp)
549
  {
550
    return gc::operator new(size, gcp);
551
  }
552

553
  inline void* gc::operator new[](GC_SIZE_T, void* p) GC_NOEXCEPT
554
  {
555
    return p;
556
  }
557

558
  inline void gc::operator delete[](void* obj) GC_NOEXCEPT
559
  {
560
    gc::operator delete(obj);
561
  }
562

563
# ifdef GC_OPERATOR_SIZED_DELETE
564
    inline void gc::operator delete[](void* obj, GC_SIZE_T size) GC_NOEXCEPT
565
    {
566
      gc::operator delete(obj, size);
567
    }
568
# endif
569

570
# ifdef GC_PLACEMENT_DELETE
571
    inline void gc::operator delete[](void*, void*) GC_NOEXCEPT {}
572

573
    inline void gc::operator delete[](void* p, GCPlacement) GC_NOEXCEPT
574
    {
575
      gc::operator delete(p);
576
    }
577
# endif
578
#endif // GC_OPERATOR_NEW_ARRAY
579

580
inline gc_cleanup::~gc_cleanup()
433,964✔
581
{
582
# ifndef GC_NO_FINALIZATION
583
    void* base = GC_base(this);
223,982✔
584
    if (0 == base) return; // Non-heap object.
237,982✔
585
    GC_register_finalizer_ignore_self(base, 0, 0, 0, 0);
209,982✔
586
# endif
587
}
223,982✔
588

589
inline void GC_CALLBACK gc_cleanup::cleanup(void* obj, void* displ)
194,584✔
590
{
591
  reinterpret_cast<gc_cleanup*>(reinterpret_cast<char*>(obj)
592
                + reinterpret_cast<GC_PTRDIFF_T>(displ))->~gc_cleanup();
194,584✔
593
}
194,584✔
594

595
inline gc_cleanup::gc_cleanup()
224,000✔
596
{
597
# ifndef GC_NO_FINALIZATION
598
    GC_finalization_proc oldProc = 0;
224,000✔
599
    void* oldData = 0; // to avoid "might be uninitialized" compiler warning
224,000✔
600
    void* this_ptr = reinterpret_cast<void*>(this);
224,000✔
601
    void* base = GC_base(this_ptr);
224,000✔
602
    if (base != 0) {
224,000✔
603
      // Don't call the debug version, since this is a real base address.
604
      GC_register_finalizer_ignore_self(base,
210,000✔
605
                reinterpret_cast<GC_finalization_proc>(cleanup),
606
                reinterpret_cast<void*>(reinterpret_cast<char*>(this_ptr) -
210,000✔
607
                                        reinterpret_cast<char*>(base)),
608
                &oldProc, &oldData);
210,000✔
609
      if (oldProc != 0) {
210,000✔
610
        GC_register_finalizer_ignore_self(base, oldProc, oldData, 0, 0);
14,000✔
611
      }
612
    }
613
# elif defined(CPPCHECK)
614
    (void)cleanup;
615
# endif
616
}
224,000✔
617

618
#ifdef GC_NAMESPACE
619
}
620
#endif
621

622
inline void* operator new(GC_SIZE_T size, GC_NS_QUALIFY(GCPlacement) gcp,
14,028,000✔
623
                          GC_NS_QUALIFY(GCCleanUpFunc) cleanup,
624
                          void* clientData)
625
{
626
  void* obj;
627
  switch (gcp) {
14,028,000✔
628
  case GC_NS_QUALIFY(UseGC):
629
    obj = GC_MALLOC(size);
14,014,000✔
630
#   ifndef GC_NO_FINALIZATION
631
      if (cleanup != 0 && obj != 0) {
14,014,000✔
632
        GC_REGISTER_FINALIZER_IGNORE_SELF(obj, cleanup, clientData, 0, 0);
14,000✔
633
      }
634
#   else
635
      (void)cleanup;
636
      (void)clientData;
637
#   endif
638
    break;
14,014,000✔
639
  case GC_NS_QUALIFY(PointerFreeGC):
640
    obj = GC_MALLOC_ATOMIC(size);
×
641
    break;
×
642
# ifdef GC_ATOMIC_UNCOLLECTABLE
643
    case GC_NS_QUALIFY(PointerFreeNoGC):
644
      obj = GC_MALLOC_ATOMIC_UNCOLLECTABLE(size);
×
645
      break;
×
646
# endif
647
  case GC_NS_QUALIFY(NoGC):
648
  default:
649
    obj = GC_MALLOC_UNCOLLECTABLE(size);
14,000✔
650
  }
651
  GC_OP_NEW_OOM_CHECK(obj);
14,028,000✔
652
  return obj;
14,028,000✔
653
}
654

655
#ifdef GC_PLACEMENT_DELETE
656
  inline void operator delete(void* obj, GC_NS_QUALIFY(GCPlacement),
657
                              GC_NS_QUALIFY(GCCleanUpFunc),
658
                              void* /* clientData */) GC_NOEXCEPT
659
  {
660
    GC_FREE(obj);
661
  }
662
#endif // GC_PLACEMENT_DELETE
663

664
#ifdef GC_OPERATOR_NEW_ARRAY
665
  inline void* operator new[](GC_SIZE_T size,
666
                              GC_NS_QUALIFY(GCPlacement) gcp,
667
                              GC_NS_QUALIFY(GCCleanUpFunc) cleanup,
668
                              void* clientData)
669
  {
670
    return ::operator new(size, gcp, cleanup, clientData);
671
  }
672
#endif // GC_OPERATOR_NEW_ARRAY
673

674
#endif /* GC_CPP_H */
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc