Workaround 'NULL==*flh is always true' cppcheck style warning in allocobj
[platform/upstream/libgc.git] / gc_cpp.cc
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 copy this code for any purpose,
8  * provided the above notices are retained on all copies.
9  */
10
11 /*************************************************************************
12 This implementation module for gc_cpp.h provides an implementation of
13 the global operators "new" and "delete" that calls the Boehm
14 allocator.  All objects allocated by this implementation will be
15 uncollectible but part of the root set of the collector.
16
17 You should ensure (using implementation-dependent techniques) that the
18 linker finds this module before the library that defines the default
19 built-in "new" and "delete".
20 **************************************************************************/
21
22 #ifdef HAVE_CONFIG_H
23 # include "config.h"
24 #endif
25
26 #ifndef GC_BUILD
27 # define GC_BUILD
28 #endif
29
30 #define GC_DONT_INCL_WINDOWS_H
31 #include "gc.h"
32
33 #include <new> // for bad_alloc, precedes include of gc_cpp.h
34
35 #include "gc_cpp.h" // for GC_OPERATOR_NEW_ARRAY, GC_NOEXCEPT
36
37 #if !(defined(_MSC_VER) || defined(__DMC__)) || defined(GC_NO_INLINE_STD_NEW)
38
39 #if defined(GC_NEW_ABORTS_ON_OOM) || defined(_LIBCPP_NO_EXCEPTIONS)
40 # define GC_ALLOCATOR_THROW_OR_ABORT() GC_abort_on_oom()
41 #else
42 // Use bad_alloc() directly instead of GC_throw_bad_alloc() call.
43 # define GC_ALLOCATOR_THROW_OR_ABORT() throw std::bad_alloc()
44 #endif
45
46 # if !defined(GC_NEW_DELETE_THROW_NOT_NEEDED) \
47     && !defined(GC_NEW_DELETE_NEED_THROW) && GC_GNUC_PREREQ(4, 2) \
48     && (__cplusplus < 201103L || defined(__clang__))
49 #   define GC_NEW_DELETE_NEED_THROW
50 # endif
51
52 # ifdef GC_NEW_DELETE_NEED_THROW
53 #   if __cplusplus < 201703L
54 #     define GC_DECL_NEW_THROW throw(std::bad_alloc)
55 #   else
56       // The "dynamic exception" syntax was deprecated in C++11
57       // and removed in C++17.
58 #     define GC_DECL_NEW_THROW noexcept(false)
59 #   endif
60 # else
61 #   define GC_DECL_NEW_THROW /* empty */
62 # endif
63
64   void* operator new(size_t size) GC_DECL_NEW_THROW {
65     void* obj = GC_MALLOC_UNCOLLECTABLE(size);
66     if (0 == obj)
67       GC_ALLOCATOR_THROW_OR_ABORT();
68     return obj;
69   }
70
71 # ifdef _MSC_VER
72     // This new operator is used by VC++ in case of Debug builds.
73     void* operator new(size_t size, int /* nBlockUse */,
74                        const char* szFileName, int nLine)
75     {
76 #     ifdef GC_DEBUG
77         void* obj = GC_debug_malloc_uncollectable(size, szFileName, nLine);
78 #     else
79         void* obj = GC_MALLOC_UNCOLLECTABLE(size);
80         (void)szFileName; (void)nLine;
81 #     endif
82       if (0 == obj)
83         GC_ALLOCATOR_THROW_OR_ABORT();
84       return obj;
85     }
86 # endif // _MSC_VER
87
88   void operator delete(void* obj) GC_NOEXCEPT {
89     GC_FREE(obj);
90   }
91
92 # if defined(GC_OPERATOR_NEW_ARRAY) && !defined(CPPCHECK)
93     void* operator new[](size_t size) GC_DECL_NEW_THROW {
94       void* obj = GC_MALLOC_UNCOLLECTABLE(size);
95       if (0 == obj)
96         GC_ALLOCATOR_THROW_OR_ABORT();
97       return obj;
98     }
99
100 #   ifdef _MSC_VER
101       // This new operator is used by VC++ 7+ in Debug builds.
102       void* operator new[](size_t size, int nBlockUse,
103                            const char* szFileName, int nLine)
104       {
105         return operator new(size, nBlockUse, szFileName, nLine);
106       }
107 #   endif // _MSC_VER
108
109     void operator delete[](void* obj) GC_NOEXCEPT {
110       GC_FREE(obj);
111     }
112 # endif // GC_OPERATOR_NEW_ARRAY
113
114 # if __cplusplus > 201103L // C++14
115     void operator delete(void* obj, size_t size) GC_NOEXCEPT {
116       (void)size; // size is ignored
117       GC_FREE(obj);
118     }
119
120 #   if defined(GC_OPERATOR_NEW_ARRAY) && !defined(CPPCHECK)
121       void operator delete[](void* obj, size_t size) GC_NOEXCEPT {
122         (void)size;
123         GC_FREE(obj);
124       }
125 #   endif
126 # endif // C++14
127
128 #endif // !_MSC_VER && !__DMC__ || GC_NO_INLINE_STD_NEW