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

bdwgc / bdwgc / 2139

12 May 2026 09:29PM UTC coverage: 80.899% (+0.5%) from 80.39%
2139

push

travis-ci

ivmai
Eliminate 'condition always true' MSVC warning in win32_unprotect_thread

* pthread_support.c [GC_WIN32_THREADS && MPROTECT_VDB]
(GC_win32_unprotect_thread): Do not check `GC_win32_dll_threads`
variable if `GC_NO_THREADS_DISCOVERY`.

7255 of 8968 relevant lines covered (80.9%)

18926688.63 hits per line

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

86.76
/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.
23
It provides basic facilities similar to those described in
24
"Safe, Efficient Garbage Collection for C++", by John R. Ellis and
25
David L. Detlefs.
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.  E.g.:
37

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

43
Collectible instances of non-class types can be allocated using `GC`
44
(or `UseGC`) placement:
45

46
```
47
  typedef int A[10];
48
  A *a = new (GC) A;
49
```
50

51
Uncollectible instances of classes derived from `gc` can be allocated
52
using `NoGC` placement:
53

54
```
55
    class A: public gc {...};
56
    A *a = new (NoGC) A; // a is uncollectible
57
```
58

59
The `new(PointerFreeGC)` syntax allows the allocation of collectible
60
objects that are not scanned by the collector.  This useful if you
61
are allocating compressed data, bitmaps, or network packets.  (In
62
the latter case, it may remove danger of unfriendly network packets
63
intentionally containing values that cause spurious memory retention.)
64

65
Both uncollectible and collectible objects can be explicitly deleted
66
with `operator delete`, which invokes an object's destructors and frees
67
its storage immediately.
68

69
A collectible object may have a cleanup function, which will be
70
invoked when the collector discovers the object to be inaccessible.
71
An object derived from `gc_cleanup` or containing a member derived
72
from `gc_cleanup` has a default cleanup function that invokes the
73
object's destructors.  Explicit cleanup functions may be specified as
74
an additional placement argument:
75

76
```
77
    A *a = ::new (GC, MyCleanup) A;
78
```
79

80
An object is considered "accessible" by the collector if it can be
81
reached by a path of pointers from `static` variables, automatic
82
variables of active functions, or from some object with cleanup
83
enabled; pointers from an object to itself are ignored.
84

85
Thus, if objects A and B both have cleanup functions, and A points at
86
B, B is considered accessible.  After A's cleanup is invoked and its
87
storage released, B will then become inaccessible and will have its
88
cleanup invoked.  If A points at B and B points to A, forming a
89
cycle, then that is considered a storage leak, and neither will be
90
collectible.  See the interface in `gc.h` file for low-level facilities
91
for handling such cycles of objects with cleanup.
92

93
The collector cannot guarantee that it will find all inaccessible
94
objects.  In practice, it finds almost all of them.
95

96
Cautions:
97

98
  1. Be sure the collector is compiled with the C++ support
99
     (e.g. `--enable-cplusplus` option is passed to `configure`).
100

101
  2. If the compiler does not support `operator new[]`, beware that an
102
     array of type `T`, where `T` is derived from `gc`, may or may not be
103
     allocated as a collectible object (it depends on the compiler).  Use
104
     the explicit GC placement to make the array collectible.  E.g.:
105

106
     ```
107
       class A: public gc {...};
108
       A *a1 = new A[10];      // collectible or uncollectible?
109
       A *a2 = new (GC) A[10]; // collectible
110
     ```
111

112
  3. The destructors of collectible arrays of objects derived from
113
     `gc_cleanup` will not be invoked properly.  E.g.:
114

115
     ```
116
       class A: public gc_cleanup {...};
117
       A *a = new (GC) A[10]; // destructors not invoked correctly
118
     ```
119
     Typically, only the destructor for the first element of the array will
120
     be invoked when the array is garbage-collected.  To get all the
121
     destructors of any array executed, you must supply an explicit
122
     cleanup function:
123

124
     ```
125
       A *a = new (GC, MyCleanUp) A[10];
126
     ```
127
     (Implementing cleanup of arrays correctly, portably, and in a way
128
     that preserves the correct exception semantics, requires a language
129
     extension, e.g. the `gc` keyword.)
130

131
  4. GC name conflicts: Many other systems seem to use the identifier `GC`
132
     as an abbreviation for "Graphics Context".  Thus, `GC` placement has
133
     been replaced by `UseGC`.  `GC` is an alias for `UseGC`, unless
134
     `GC_NAME_CONFLICT` macro is defined.
135
*/
136

137
#include "gc.h"
138

139
#ifdef GC_INCLUDE_NEW
140
#  include <new> // for `std`, `bad_alloc`
141
#endif
142

143
#if defined(GC_INCLUDE_NEW) && (__cplusplus >= 201103L)
144
#  define GC_PTRDIFF_T std::ptrdiff_t
145
#  define GC_SIZE_T std::size_t
146
#else
147
#  define GC_PTRDIFF_T ptrdiff_t
148
#  define GC_SIZE_T size_t
149
#endif
150

151
#ifdef GC_NAMESPACE
152
#  define GC_NS_QUALIFY(T) boehmgc::T
153
#else
154
#  define GC_NS_QUALIFY(T) T
155
#endif
156

157
#if !defined(GC_NO_OPERATOR_NEW_ARRAY)                  \
158
    && !defined(_ENABLE_ARRAYNEW) /*< Digital Mars */   \
159
    && (defined(__BORLANDC__) && (__BORLANDC__ < 0x450) \
160
        || (defined(__GNUC__) && !GC_GNUC_PREREQ(2, 6)) \
161
        || (defined(_MSC_VER) && _MSC_VER <= 1020)      \
162
        || (defined(__WATCOMC__) && __WATCOMC__ < 1050))
163
#  define GC_NO_OPERATOR_NEW_ARRAY
164
#endif
165

166
#if !defined(GC_NO_OPERATOR_NEW_ARRAY) && !defined(GC_OPERATOR_NEW_ARRAY)
167
#  define GC_OPERATOR_NEW_ARRAY
168
#endif
169

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

181
#if (!defined(__BORLANDC__) || __BORLANDC__ > 0x0620) && !defined(__sgi) \
182
    && !defined(__WATCOMC__) && (!defined(_MSC_VER) || _MSC_VER > 1020)
183
#  define GC_PLACEMENT_DELETE
184
#endif
185

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

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

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

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

219
#if defined(GC_NEW_ABORTS_ON_OOM) || defined(_LIBCPP_NO_EXCEPTIONS)
220
#  define GC_OP_NEW_OOM_CHECK(obj) \
221
    do {                           \
222
      if (!(obj))                  \
223
        GC_abort_on_oom();         \
224
    } while (0)
225
#elif defined(GC_INCLUDE_NEW)
226
#  define GC_OP_NEW_OOM_CHECK(obj) \
227
    if (obj) {                     \
228
    } else                         \
229
      throw std::bad_alloc()
230
#else
231
// The platform `new` header file is not included, so `bad_alloc` cannot
232
// be thrown directly.
233
GC_API GC_OOM_ABORT_THROW_ATTRIBUTE void GC_CALL GC_throw_bad_alloc();
234
#  define GC_OP_NEW_OOM_CHECK(obj) \
235
    if (obj) {                     \
236
    } else                         \
237
      GC_throw_bad_alloc()
238
#endif // !GC_NEW_ABORTS_ON_OOM && !GC_INCLUDE_NEW
239

240
#ifdef GC_NAMESPACE
241
namespace boehmgc
242
{
243
#endif
244

245
enum GCPlacement {
246
  UseGC,
247
#ifndef GC_NAME_CONFLICT
248
  GC = UseGC,
249
#endif
250
  NoGC,
251
  PointerFreeGC
252
#ifdef GC_ATOMIC_UNCOLLECTABLE
253
  ,
254
  PointerFreeNoGC
255
#endif
256
};
257

258
// Instances of classes derived from `gc` will be allocated in the collected
259
// heap by default, unless an explicit `NoGC` placement is specified.
260
class gc
261
{
262
public:
263
  inline void *operator new(GC_SIZE_T);
264
  inline void *operator new(GC_SIZE_T, GCPlacement);
265

266
  // Must be redefined here, since the other overloadings hide
267
  // the global definition.
268
  inline void *operator new(GC_SIZE_T, void *) GC_NOEXCEPT;
269

270
  inline void operator delete(void *) GC_NOEXCEPT;
271
#ifdef GC_OPERATOR_SIZED_DELETE
272
  inline void operator delete(void *, GC_SIZE_T) GC_NOEXCEPT;
273
#endif
274

275
#ifdef GC_PLACEMENT_DELETE
276
  // Called if construction fails.
277
  inline void operator delete(void *, GCPlacement) GC_NOEXCEPT;
278

279
  inline void operator delete(void *, void *) GC_NOEXCEPT;
280
#endif // GC_PLACEMENT_DELETE
281

282
#ifdef GC_OPERATOR_NEW_ARRAY
283
  inline void *operator new[](GC_SIZE_T);
284
  inline void *operator new[](GC_SIZE_T, GCPlacement);
285
  inline void *operator new[](GC_SIZE_T, void *) GC_NOEXCEPT;
286
  inline void operator delete[](void *) GC_NOEXCEPT;
287
#  ifdef GC_OPERATOR_SIZED_DELETE
288
  inline void operator delete[](void *, GC_SIZE_T) GC_NOEXCEPT;
289
#  endif
290
#  ifdef GC_PLACEMENT_DELETE
291
  inline void operator delete[](void *, GCPlacement) GC_NOEXCEPT;
292
  inline void operator delete[](void *, void *) GC_NOEXCEPT;
293
#  endif
294
#endif
295
};
296

297
// Instances of classes derived from gc_cleanup will be allocated in the
298
// collected heap by default.  When the collector discovers an inaccessible
299
// object derived from `gc_cleanup` or containing a member derived from
300
// `gc_cleanup`, its destructors will be invoked.
301
class gc_cleanup : virtual public gc
302
{
303
public:
304
  inline gc_cleanup();
305
  inline virtual ~gc_cleanup();
306

307
private:
308
  inline static void GC_CALLBACK cleanup(void *obj, void *displ);
309
};
310

311
extern "C" {
312
typedef void(GC_CALLBACK *GCCleanUpFunc)(void *obj, void *clientData);
313
}
314

315
#ifdef GC_NAMESPACE
316
}
317
#endif
318

319
#ifdef _MSC_VER
320
// Disable warning that "no matching operator delete found; memory will
321
// not be freed if initialization throws an exception"
322
#  pragma warning(disable : 4291)
323
// TODO: "non-member operator new or delete may not be declared inline"
324
// warning is disabled for now.
325
#  pragma warning(disable : 4595)
326
#endif
327

328
// Allocates a collectible or uncollectible object, according to the
329
// value of `gcp`.
330
// For collectible objects, if `cleanup` is non-null, then when the
331
// allocated object `obj` becomes inaccessible, the collector will
332
// invoke `cleanup(obj, clientData)` but will not invoke the object's
333
// destructors.  It is an error to explicitly `delete` an object
334
// allocated with a non-null `cleanup`.
335
// It is an error to specify a non-null `cleanup` with `NoGC` or for
336
// classes derived from `gc_cleanup` or containing members derived
337
// from `gc_cleanup`.
338
inline void *operator new(GC_SIZE_T, GC_NS_QUALIFY(GCPlacement) /* `gcp` */,
339
                          GC_NS_QUALIFY(GCCleanUpFunc) = 0 /* `cleanup` */,
340
                          void * /* `clientData` */ = 0);
341

342
#ifdef GC_PLACEMENT_DELETE
343
inline void operator delete(void *, GC_NS_QUALIFY(GCPlacement),
344
                            GC_NS_QUALIFY(GCCleanUpFunc), void *) GC_NOEXCEPT;
345
#endif
346

347
// MS SAL annotations for `operator new`.
348
#ifdef _MSC_VER
349
#  ifndef _Check_return_
350
#    define _Check_return_
351
#  endif
352
#  ifndef _In_
353
#    define _In_
354
#  endif
355
#  ifndef _In_z_
356
#    define _In_z_
357
#  endif
358
#  ifndef _Ret_maybenull_
359
#    define _Ret_maybenull_
360
#  endif
361
#  ifndef _Ret_notnull_
362
#    define _Ret_notnull_
363
#  endif
364
#  ifndef _Post_writable_byte_size_
365
#    define _Post_writable_byte_size_(s)
366
#  endif
367
#  ifndef _Success_
368
#    define _Success_(b)
369
#  endif
370
#  define GC_OPERATOR_NEW_ATTR(s) _Ret_notnull_ _Post_writable_byte_size_(s)
371
#  define GC_OPERATOR_NOTHROW_NEW_ATTR(s) \
372
    _Ret_maybenull_ _Success_(return != NULL) _Post_writable_byte_size_(s)
373
#else
374
#  define GC_OPERATOR_NEW_ATTR(s)         /*< empty */
375
#  define GC_OPERATOR_NOTHROW_NEW_ATTR(s) /* `GC_ATTR_MALLOC` */
376
#endif
377

378
#ifdef GC_INLINE_STD_NEW
379

380
#  ifdef GC_OPERATOR_NEW_ARRAY
381
inline GC_OPERATOR_NEW_ATTR(size) void *
382
operator new[](GC_SIZE_T size) GC_DECL_NEW_THROW
383
{
384
  void *obj = GC_MALLOC_UNCOLLECTABLE(size);
385
  GC_OP_NEW_OOM_CHECK(obj);
386
  return obj;
387
}
388

389
inline void
390
operator delete[](void *obj) GC_NOEXCEPT
391
{
392
  GC_FREE(obj);
393
}
394

395
#    ifdef GC_OPERATOR_NEW_NOTHROW
396
inline GC_OPERATOR_NOTHROW_NEW_ATTR(size) void *
397
operator new[](GC_SIZE_T size, const std::nothrow_t &) GC_NOEXCEPT
398
{
399
  return GC_MALLOC_UNCOLLECTABLE(size);
400
}
401

402
inline void
403
operator delete[](void *obj, const std::nothrow_t &) GC_NOEXCEPT
404
{
405
  GC_FREE(obj);
406
}
407
#    endif
408
#  endif // GC_OPERATOR_NEW_ARRAY
409

410
inline GC_OPERATOR_NEW_ATTR(size) void *
411
operator new(GC_SIZE_T size) GC_DECL_NEW_THROW
412
{
413
  void *obj = GC_MALLOC_UNCOLLECTABLE(size);
414
  GC_OP_NEW_OOM_CHECK(obj);
415
  return obj;
416
}
417

418
inline void
419
operator delete(void *obj) GC_NOEXCEPT
420
{
421
  GC_FREE(obj);
422
}
423

424
#  ifdef GC_OPERATOR_NEW_NOTHROW
425
inline GC_OPERATOR_NOTHROW_NEW_ATTR(size) void *
426
operator new(GC_SIZE_T size, const std::nothrow_t &) GC_NOEXCEPT
427
{
428
  return GC_MALLOC_UNCOLLECTABLE(size);
429
}
430

431
inline void
432
operator delete(void *obj, const std::nothrow_t &) GC_NOEXCEPT
433
{
434
  GC_FREE(obj);
435
}
436
#  endif // GC_OPERATOR_NEW_NOTHROW
437

438
#  ifdef GC_OPERATOR_SIZED_DELETE
439
inline void
440
operator delete(void *obj, GC_SIZE_T) GC_NOEXCEPT
441
{
442
  GC_FREE(obj);
443
}
444

445
#    ifdef GC_OPERATOR_NEW_ARRAY
446
inline void
447
operator delete[](void *obj, GC_SIZE_T) GC_NOEXCEPT
448
{
449
  GC_FREE(obj);
450
}
451
#    endif
452
#  endif // GC_OPERATOR_SIZED_DELETE
453

454
#  ifdef _MSC_VER
455
// This new operator is used by VC++ in case of Debug builds.
456
inline _Check_return_
457
GC_OPERATOR_NEW_ATTR(size) void *
458
operator new(_In_ GC_SIZE_T size, _In_ int /* `nBlockUse` */,
459
             _In_z_ const char *szFileName, _In_ int nLine)
460
{
461
#    ifdef GC_DEBUG
462
  void *obj = GC_debug_malloc_uncollectable(size, szFileName, nLine);
463
#    else
464
  void *obj = GC_MALLOC_UNCOLLECTABLE(size);
465
  (void)szFileName;
466
  (void)nLine;
467
#    endif
468
  GC_OP_NEW_OOM_CHECK(obj);
469
  return obj;
470
}
471

472
#    ifdef GC_OPERATOR_NEW_ARRAY
473
// This new operator is used by VC++ 7+ in Debug builds.
474
inline _Check_return_
475
GC_OPERATOR_NEW_ATTR(size) void *
476
operator new[](_In_ GC_SIZE_T size, _In_ int nBlockUse,
477
               _In_z_ const char *szFileName, _In_ int nLine)
478
{
479
  return operator new(size, nBlockUse, szFileName, nLine);
480
}
481
#    endif
482
#  endif // _MSC_VER
483

484
#elif defined(GC_NO_INLINE_STD_NEW) && defined(_MSC_VER)
485

486
// The following ensures that the system default `operator new[]` does not
487
// get undefined, which is what seems to happen on VC++ 6 for some reason
488
// if we define a multi-argument `operator new[]`.
489
// There seems to be no way to redirect new in this environment without
490
// including this everywhere.
491
#  ifdef GC_OPERATOR_NEW_ARRAY
492
GC_OPERATOR_NEW_ATTR(size)
493
void *operator new[](GC_SIZE_T size) GC_DECL_NEW_THROW;
494

495
void operator delete[](void *) GC_NOEXCEPT;
496
#    ifdef GC_OPERATOR_NEW_NOTHROW
497
GC_OPERATOR_NOTHROW_NEW_ATTR(size)
498
void *operator new[](GC_SIZE_T size, const std::nothrow_t &) GC_NOEXCEPT;
499

500
void operator delete[](void *, const std::nothrow_t &) GC_NOEXCEPT;
501
#    endif
502
#    ifdef GC_OPERATOR_SIZED_DELETE
503
void operator delete[](void *, GC_SIZE_T) GC_NOEXCEPT;
504
#    endif
505

506
_Check_return_ GC_OPERATOR_NEW_ATTR(size) void *
507
operator new[](_In_ GC_SIZE_T size, _In_ int /* `nBlockUse` */,
508
               _In_z_ const char * /* `szFileName` */, _In_ int /* `nLine` */);
509
#  endif // GC_OPERATOR_NEW_ARRAY
510

511
GC_OPERATOR_NEW_ATTR(size)
512
void *operator new(GC_SIZE_T size) GC_DECL_NEW_THROW;
513

514
void operator delete(void *) GC_NOEXCEPT;
515
#  ifdef GC_OPERATOR_NEW_NOTHROW
516
GC_OPERATOR_NOTHROW_NEW_ATTR(size)
517
void *operator new(GC_SIZE_T size, const std::nothrow_t &) GC_NOEXCEPT;
518

519
void operator delete(void *, const std::nothrow_t &) GC_NOEXCEPT;
520
#  endif
521
#  ifdef GC_OPERATOR_SIZED_DELETE
522
void operator delete(void *, GC_SIZE_T) GC_NOEXCEPT;
523
#  endif
524

525
_Check_return_ GC_OPERATOR_NEW_ATTR(size) void *
526
operator new(_In_ GC_SIZE_T size, _In_ int /* `nBlockUse` */,
527
             _In_z_ const char * /* `szFileName` */, _In_ int /* `nLine` */);
528

529
#endif // GC_NO_INLINE_STD_NEW && _MSC_VER
530

531
#ifdef GC_OPERATOR_NEW_ARRAY
532
// The `operator new` for arrays, identical to the above.
533
inline void *operator new[](GC_SIZE_T, GC_NS_QUALIFY(GCPlacement),
534
                            GC_NS_QUALIFY(GCCleanUpFunc) = 0,
535
                            void * /* `clientData` */ = 0);
536
#endif // GC_OPERATOR_NEW_ARRAY
537

538
// Inline implementation.
539

540
#ifdef GC_NAMESPACE
541
namespace boehmgc
542
{
543
#endif
544

545
inline void *
546
gc::operator new(GC_SIZE_T size)
14,196,000✔
547
{
548
  void *obj = GC_MALLOC(size);
14,196,000✔
549
  GC_OP_NEW_OOM_CHECK(obj);
14,196,000✔
550
  return obj;
14,196,000✔
551
}
552

553
inline void *
554
gc::operator new(GC_SIZE_T size, GCPlacement gcp)
37,100,262✔
555
{
556
  void *obj;
557
  switch (gcp) {
37,100,262✔
558
  case UseGC:
18,923,692✔
559
    obj = GC_MALLOC(size);
18,923,692✔
560
    break;
18,923,692✔
561
  case PointerFreeGC:
9,549,198✔
562
    obj = GC_MALLOC_ATOMIC(size);
9,549,198✔
563
    break;
9,549,198✔
564
#ifdef GC_ATOMIC_UNCOLLECTABLE
565
  case PointerFreeNoGC:
5,642,948✔
566
    obj = GC_MALLOC_ATOMIC_UNCOLLECTABLE(size);
5,642,948✔
567
    break;
5,642,948✔
568
#endif
569
  case NoGC:
2,984,424✔
570
  default:
571
    obj = GC_MALLOC_UNCOLLECTABLE(size);
2,984,424✔
572
  }
573
  GC_OP_NEW_OOM_CHECK(obj);
37,100,262✔
574
  return obj;
37,100,262✔
575
}
576

577
inline void *
578
gc::operator new(GC_SIZE_T, void *p) GC_NOEXCEPT
579
{
580
  return p;
581
}
582

583
inline void
584
gc::operator delete(void *obj) GC_NOEXCEPT
11,202,678✔
585
{
586
  GC_FREE(obj);
11,202,678✔
587
}
11,202,678✔
588

589
#ifdef GC_OPERATOR_SIZED_DELETE
590
inline void
591
gc::operator delete(void *obj, GC_SIZE_T) GC_NOEXCEPT
592
{
593
  GC_FREE(obj);
594
}
595
#endif
596

597
#ifdef GC_PLACEMENT_DELETE
598
inline void
599
gc::operator delete(void *, void *) GC_NOEXCEPT
600
{
601
}
602

603
inline void
604
gc::operator delete(void *obj, GCPlacement) GC_NOEXCEPT
×
605
{
606
  GC_FREE(obj);
×
607
}
×
608
#endif // GC_PLACEMENT_DELETE
609

610
#ifdef GC_OPERATOR_NEW_ARRAY
611
inline void *
612
gc::operator new[](GC_SIZE_T size)
613
{
614
  return gc::operator new(size);
615
}
616

617
inline void *
618
gc::operator new[](GC_SIZE_T size, GCPlacement gcp)
3,947,058✔
619
{
620
  return gc::operator new(size, gcp);
3,947,058✔
621
}
622

623
inline void *
624
gc::operator new[](GC_SIZE_T, void *p) GC_NOEXCEPT
625
{
626
  return p;
627
}
628

629
inline void
630
gc::operator delete[](void *obj) GC_NOEXCEPT
1,681,100✔
631
{
632
  gc::operator delete(obj);
1,681,100✔
633
}
1,681,100✔
634

635
#  ifdef GC_OPERATOR_SIZED_DELETE
636
inline void
637
gc::operator delete[](void *obj, GC_SIZE_T size) GC_NOEXCEPT
638
{
639
  gc::operator delete(obj, size);
640
}
641
#  endif
642

643
#  ifdef GC_PLACEMENT_DELETE
644
inline void
645
gc::operator delete[](void *, void *) GC_NOEXCEPT
646
{
647
}
648

649
inline void
650
gc::operator delete[](void *p, GCPlacement) GC_NOEXCEPT
651
{
652
  gc::operator delete(p);
653
}
654
#  endif
655
#endif // GC_OPERATOR_NEW_ARRAY
656

657
inline gc_cleanup::~gc_cleanup()
223,981✔
658
{
659
#ifndef GC_NO_FINALIZATION
660
  void *base = GC_base(this);
223,981✔
661
  if (0 == base)
223,981✔
662
    return; // Non-heap object.
14,000✔
663
  GC_register_finalizer_ignore_self(base, 0, 0, 0, 0);
209,981✔
664
#endif
665
}
666

667
inline void GC_CALLBACK
668
gc_cleanup::cleanup(void *obj, void *displ)
194,583✔
669
{
670
  reinterpret_cast<gc_cleanup *>(
194,583✔
671
      reinterpret_cast<char *>(obj)
672
      + static_cast<GC_PTRDIFF_T>(reinterpret_cast<GC_uintptr_t>(displ)))
194,583✔
673
      ->~gc_cleanup();
194,583✔
674
#ifdef CPPCHECK
675
  GC_noop1_ptr(displ);
676
#endif
677
}
194,583✔
678

679
inline gc_cleanup::gc_cleanup()
224,000✔
680
{
681
#ifndef GC_NO_FINALIZATION
682
  GC_finalization_proc oldProc = 0;
224,000✔
683
  void *oldData = 0; // to avoid "might be uninitialized" compiler warning
224,000✔
684
  void *this_ptr = reinterpret_cast<void *>(this);
224,000✔
685
  void *base = GC_base(this_ptr);
224,000✔
686
  if (base != 0) {
224,000✔
687
    // Do not call the debug variant, since this is a real base address.
688
    GC_register_finalizer_ignore_self(
210,000✔
689
        base, reinterpret_cast<GC_finalization_proc>(cleanup),
690
        reinterpret_cast<void *>(
691
            static_cast<GC_uintptr_t>(reinterpret_cast<char *>(this_ptr)
692
                                      - reinterpret_cast<char *>(base))),
210,000✔
693
        &oldProc, &oldData);
694
    if (oldProc != 0) {
210,000✔
695
      GC_register_finalizer_ignore_self(base, oldProc, oldData, 0, 0);
14,000✔
696
    }
697
  }
698
#elif defined(CPPCHECK)
699
  (void)cleanup;
700
#endif
701
}
224,000✔
702

703
#ifdef GC_NAMESPACE
704
}
705
#endif
706

707
inline void *
708
operator new(GC_SIZE_T size, GC_NS_QUALIFY(GCPlacement) gcp,
14,028,000✔
709
             GC_NS_QUALIFY(GCCleanUpFunc) cleanup, void *clientData)
710
{
711
  void *obj;
712
  switch (gcp) {
14,028,000✔
713
  case GC_NS_QUALIFY(UseGC):
14,014,000✔
714
    obj = GC_MALLOC(size);
14,014,000✔
715
#ifndef GC_NO_FINALIZATION
716
    if (cleanup != 0 && obj != 0) {
14,014,000✔
717
      GC_REGISTER_FINALIZER_IGNORE_SELF(obj, cleanup, clientData, 0, 0);
14,000✔
718
    }
719
#else
720
    (void)cleanup;
721
    (void)clientData;
722
#endif
723
    break;
14,014,000✔
724
  case GC_NS_QUALIFY(PointerFreeGC):
×
725
    obj = GC_MALLOC_ATOMIC(size);
×
726
    break;
×
727
#ifdef GC_ATOMIC_UNCOLLECTABLE
728
  case GC_NS_QUALIFY(PointerFreeNoGC):
×
729
    obj = GC_MALLOC_ATOMIC_UNCOLLECTABLE(size);
×
730
    break;
×
731
#endif
732
  case GC_NS_QUALIFY(NoGC):
14,000✔
733
  default:
734
    obj = GC_MALLOC_UNCOLLECTABLE(size);
14,000✔
735
  }
736
  GC_OP_NEW_OOM_CHECK(obj);
14,028,000✔
737
  return obj;
14,028,000✔
738
}
739

740
#ifdef GC_PLACEMENT_DELETE
741
inline void
742
operator delete(void *obj, GC_NS_QUALIFY(GCPlacement),
743
                GC_NS_QUALIFY(GCCleanUpFunc),
744
                void * /* `clientData` */) GC_NOEXCEPT
745
{
746
  GC_FREE(obj);
747
}
748
#endif // GC_PLACEMENT_DELETE
749

750
#ifdef GC_OPERATOR_NEW_ARRAY
751
inline void *
752
operator new[](GC_SIZE_T size, GC_NS_QUALIFY(GCPlacement) gcp,
753
               GC_NS_QUALIFY(GCCleanUpFunc) cleanup, void *clientData)
754
{
755
  return ::operator new(size, gcp, cleanup, clientData);
756
}
757
#endif
758

759
#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