gc_config_macros.h raw
1 /*
2 * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
3 * Copyright (c) 1996 by Silicon Graphics. All rights reserved.
4 * Copyright (c) 1998 by Fergus Henderson. All rights reserved.
5 * Copyright (c) 2000-2009 by Hewlett-Packard Development Company.
6 * All rights reserved.
7 * Copyright (c) 2008-2020 Ivan Maidanski
8 *
9 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
10 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
11 *
12 * Permission is hereby granted to use or copy this program
13 * for any purpose, provided the above notices are retained on all copies.
14 * Permission to modify the code and to distribute modified code is granted,
15 * provided the above notices are retained, and a notice that the code was
16 * modified is included with the above copyright notice.
17 */
18
19 /*
20 * This should never be included directly; it is included only from
21 * `gc.h` file. We separate it only to make `gc.h` file more suitable
22 * as documentation.
23 */
24 #if defined(GC_H)
25
26 /* Convenient internal macro to test version of gcc. */
27 # if defined(__GNUC__) && defined(__GNUC_MINOR__)
28 # define GC_GNUC_PREREQ(major, minor) \
29 ((__GNUC__ << 8) + __GNUC_MINOR__ >= ((major) << 8) + (minor))
30 # else
31 # define GC_GNUC_PREREQ(major, minor) 0 /*< false */
32 # endif
33
34 /*
35 * A macro to define integer types of a pointer size. There seems to
36 * be no way to do this even semi-portably. The following is probably
37 * no better/worse than almost anything else.
38 * The ANSI standard suggests that `size_t` and `ptrdiff_t` might be
39 * better choices. But those had incorrect definitions on some older
40 * systems; notably `typedef int size_t` is wrong.
41 */
42 # ifdef _WIN64
43 # if defined(__int64) && !defined(CPPCHECK)
44 # define GC_SIGNEDWORD __int64
45 # else
46 # define GC_SIGNEDWORD long long
47 # endif
48 # else
49 # define GC_SIGNEDWORD long
50 # endif
51 # define GC_UNSIGNEDWORD unsigned GC_SIGNEDWORD
52
53 /* Size of a pointer in bytes. */
54 # if defined(__SIZEOF_POINTER__)
55 # define GC_SIZEOF_PTR __SIZEOF_POINTER__
56 # elif defined(__LP64__) || defined(_LP64) || defined(_WIN64) \
57 || defined(__alpha__) || defined(__arch64__) || defined(__powerpc64__) \
58 || defined(__s390x__) || defined(__sparcv9) \
59 || (defined(__x86_64__) && !defined(__ILP32__))
60 # define GC_SIZEOF_PTR 8
61 # else
62 # define GC_SIZEOF_PTR 4
63 # endif
64
65 /*
66 * The return type of `GC_get_version()`. A 32-bit unsigned integer
67 * or longer.
68 */
69 # define GC_VERSION_VAL_T unsigned
70
71 /*
72 * Some tests for old macros. These violate our namespace rules and
73 * are deprecated. Use the `GC_` names instead.
74 */
75 # if defined(SOLARIS_THREADS) || defined(_SOLARIS_THREADS) \
76 || defined(_SOLARIS_PTHREADS) || defined(GC_SOLARIS_PTHREADS)
77 /*
78 * We no longer support old style Solaris threads.
79 * `GC_SOLARIS_THREADS` now means `pthreads`.
80 */
81 # ifndef GC_SOLARIS_THREADS
82 # define GC_SOLARIS_THREADS
83 # endif
84 # endif
85 # if defined(IRIX_THREADS)
86 # define GC_IRIX_THREADS
87 # endif
88 # if defined(DGUX_THREADS) && !defined(GC_DGUX386_THREADS)
89 # define GC_DGUX386_THREADS
90 # endif
91 # if defined(AIX_THREADS)
92 # define GC_AIX_THREADS
93 # endif
94 # if defined(HPUX_THREADS)
95 # define GC_HPUX_THREADS
96 # endif
97 # if defined(OSF1_THREADS)
98 # define GC_OSF1_THREADS
99 # endif
100 # if defined(LINUX_THREADS)
101 # define GC_LINUX_THREADS
102 # endif
103 # if defined(WIN32_THREADS)
104 # define GC_WIN32_THREADS
105 # endif
106 # if defined(RTEMS_THREADS)
107 # define GC_RTEMS_PTHREADS
108 # endif
109 # if defined(USE_LD_WRAP)
110 # define GC_USE_LD_WRAP
111 # endif
112
113 # if defined(GC_WIN32_PTHREADS) && !defined(GC_WIN32_THREADS)
114 /* Using pthreads-win32 library (or other Win32 implementation). */
115 # define GC_WIN32_THREADS
116 # endif
117
118 # if defined(GC_AIX_THREADS) || defined(GC_DARWIN_THREADS) \
119 || defined(GC_DGUX386_THREADS) || defined(GC_FREEBSD_THREADS) \
120 || defined(GC_HPUX_THREADS) || defined(GC_IRIX_THREADS) \
121 || defined(GC_LINUX_THREADS) || defined(GC_NETBSD_THREADS) \
122 || defined(GC_OPENBSD_THREADS) || defined(GC_OSF1_THREADS) \
123 || defined(GC_SOLARIS_THREADS) || defined(GC_WIN32_THREADS) \
124 || defined(GC_RTEMS_PTHREADS)
125 # ifndef GC_THREADS
126 # define GC_THREADS
127 # endif
128 # elif defined(GC_THREADS)
129 # if defined(__linux__) || defined(__native_client__)
130 # define GC_LINUX_THREADS
131 # elif defined(__OpenBSD__)
132 # define GC_OPENBSD_THREADS
133 # elif defined(_PA_RISC1_1) || defined(_PA_RISC2_0) || defined(hppa) \
134 || defined(__HPPA) || (defined(__ia64) && defined(_HPUX_SOURCE))
135 # define GC_HPUX_THREADS
136 # elif defined(__HAIKU__)
137 # define GC_HAIKU_THREADS
138 # elif (defined(__DragonFly__) || defined(__FreeBSD_kernel__) \
139 || defined(__FreeBSD__)) \
140 && !defined(GC_NO_FREEBSD)
141 # define GC_FREEBSD_THREADS
142 # elif defined(__NetBSD__)
143 # define GC_NETBSD_THREADS
144 # elif defined(__alpha) || defined(__alpha__) /*< not Linux, not xBSD */
145 # define GC_OSF1_THREADS
146 # elif (defined(mips) || defined(__mips) || defined(_mips)) \
147 && !(defined(nec_ews) || defined(_nec_ews) || defined(ultrix) \
148 || defined(__ultrix))
149 # define GC_IRIX_THREADS
150 # elif defined(__sparc) /* `&& !defined(__linux__)` */ \
151 || ((defined(sun) || defined(__sun)) \
152 && (defined(i386) || defined(__i386__) || defined(__amd64) \
153 || defined(__amd64__)))
154 # define GC_SOLARIS_THREADS
155 # elif defined(__APPLE__) && defined(__MACH__)
156 # define GC_DARWIN_THREADS
157 # endif
158 # if defined(DGUX) && (defined(i386) || defined(__i386__))
159 # define GC_DGUX386_THREADS
160 # endif
161 # if defined(_AIX)
162 # define GC_AIX_THREADS
163 # endif
164 # if (defined(_WIN32) || defined(_MSC_VER) || defined(__BORLANDC__) \
165 || defined(__CYGWIN32__) || defined(__CYGWIN__) \
166 || defined(__CEGCC__) || defined(_WIN32_WCE) \
167 || defined(__MINGW32__)) \
168 && !defined(GC_WIN32_THREADS)
169 /* Either POSIX or native Win32 threads. */
170 # define GC_WIN32_THREADS
171 # endif
172 # if defined(__rtems__) && (defined(i386) || defined(__i386__))
173 # define GC_RTEMS_PTHREADS
174 # endif
175 # endif /* GC_THREADS */
176
177 # undef GC_PTHREADS
178 # if (!defined(GC_WIN32_THREADS) || defined(GC_WIN32_PTHREADS) \
179 || defined(__CYGWIN32__) || defined(__CYGWIN__)) \
180 && defined(GC_THREADS) && !defined(NN_PLATFORM_CTR) \
181 && !defined(NN_BUILD_TARGET_PLATFORM_NX)
182 /* POSIX threads (`pthreads`). */
183 # define GC_PTHREADS
184 # endif
185
186 # if !defined(_PTHREADS) && defined(GC_NETBSD_THREADS)
187 # define _PTHREADS
188 # endif
189
190 # if defined(GC_DGUX386_THREADS) && !defined(_POSIX4A_DRAFT10_SOURCE)
191 # define _POSIX4A_DRAFT10_SOURCE 1
192 # endif
193
194 # if !defined(_REENTRANT) && defined(GC_PTHREADS) \
195 && !defined(GC_WIN32_THREADS)
196 /*
197 * Better late than never. This fails if system headers that depend
198 * on this were previously included.
199 */
200 # define _REENTRANT 1
201 # endif
202
203 # if defined(__clang__) && defined(__CYGWIN__) && defined(GC_THREADS) \
204 && defined(__LP64__)
205 /*
206 * Workaround "__stdcall__ ignored for this target" clang warning.
207 * Note: `__stdcall` is defined implicitly based on `__stdcall__`.
208 */
209 # define __stdcall__ /*< empty */
210 # endif
211
212 # define __GC
213 # if !defined(_WIN32_WCE) || defined(__GNUC__)
214 # include <stddef.h>
215 # if defined(__MINGW32__) && !defined(_WIN32_WCE) \
216 || defined(__CHERI_PURE_CAPABILITY__)
217 # include <stdint.h>
218 /*
219 * We mention `uintptr_t`. Perhaps this should be included in pure
220 * MS environments as well.
221 */
222 # endif
223 # else
224 /* Yet more kludges for WinCE. */
225 # include <stdlib.h> /*< for `size_t` */
226 # ifndef _PTRDIFF_T_DEFINED
227 /* `ptrdiff_t` is not defined. */
228 # define _PTRDIFF_T_DEFINED
229 typedef long ptrdiff_t;
230 # endif
231 # endif /* _WIN32_WCE */
232
233 # if !defined(GC_NOT_DLL) && !defined(GC_DLL) \
234 && ((defined(_DLL) && !defined(__GNUC__)) \
235 || (defined(DLL_EXPORT) && defined(GC_BUILD)))
236 # define GC_DLL
237 # endif
238
239 # if defined(GC_DLL) && !defined(GC_API)
240
241 # if defined(__CEGCC__)
242 # if defined(GC_BUILD)
243 # define GC_API __declspec(dllexport)
244 # else
245 # define GC_API __declspec(dllimport)
246 # endif
247
248 # elif defined(__MINGW32__)
249 # if defined(__cplusplus) && defined(GC_BUILD)
250 # define GC_API extern __declspec(dllexport)
251 # elif defined(GC_BUILD) || defined(__MINGW32_DELAY_LOAD__)
252 # define GC_API __declspec(dllexport)
253 # else
254 # define GC_API extern __declspec(dllimport)
255 # endif
256
257 # elif defined(_MSC_VER) || defined(__DMC__) || defined(__BORLANDC__) \
258 || defined(__CYGWIN__)
259 # ifdef GC_BUILD
260 # define GC_API extern __declspec(dllexport)
261 # else
262 # define GC_API __declspec(dllimport)
263 # endif
264
265 # elif defined(__WATCOMC__)
266 # ifdef GC_BUILD
267 # define GC_API extern __declspec(dllexport)
268 # else
269 # define GC_API extern __declspec(dllimport)
270 # endif
271
272 # elif defined(__SYMBIAN32__)
273 # ifdef GC_BUILD
274 # define GC_API extern EXPORT_C
275 # else
276 # define GC_API extern IMPORT_C
277 # endif
278
279 # elif defined(__GNUC__)
280 /* Only matters if used in conjunction with `-fvisibility=hidden` option. */
281 # if defined(GC_BUILD) && !defined(GC_NO_VISIBILITY) \
282 && (GC_GNUC_PREREQ(4, 0) || defined(GC_VISIBILITY_HIDDEN_SET))
283 # define GC_API extern __attribute__((__visibility__("default")))
284 # endif
285 # endif
286 # endif /* GC_DLL */
287
288 # ifndef GC_API
289 # define GC_API extern
290 # endif
291
292 # ifndef GC_CALL
293 # define GC_CALL
294 # endif
295
296 # ifndef GC_CALLBACK
297 # define GC_CALLBACK GC_CALL
298 # endif
299
300 # ifndef GC_ATTR_MALLOC
301 /*
302 * `malloc` attribute should be used for all `malloc`-like functions
303 * (to tell the compiler that a function may be treated as if any
304 * non-`NULL` pointer it returns cannot alias any other pointer valid
305 * when the function returns). If the client code violates this rule
306 * by using custom `GC_oom_func`, then the client should define
307 * `GC_OOM_FUNC_RETURNS_ALIAS` macro.
308 */
309 # ifdef GC_OOM_FUNC_RETURNS_ALIAS
310 # define GC_ATTR_MALLOC /*< empty */
311 # elif GC_GNUC_PREREQ(3, 1)
312 # define GC_ATTR_MALLOC __attribute__((__malloc__))
313 # elif defined(_MSC_VER) && (_MSC_VER >= 1900) && !defined(__EDG__)
314 # define GC_ATTR_MALLOC \
315 __declspec(allocator) __declspec(noalias) __declspec(restrict)
316 # elif defined(_MSC_VER) && _MSC_VER >= 1400
317 # define GC_ATTR_MALLOC __declspec(noalias) __declspec(restrict)
318 # else
319 # define GC_ATTR_MALLOC
320 # endif
321 # endif
322
323 # ifndef GC_ATTR_ALLOC_SIZE
324 /* `alloc_size` attribute improves `__builtin_object_size` correctness. */
325 # undef GC_ATTR_CALLOC_SIZE
326 # ifdef __clang__
327 # if __has_attribute(__alloc_size__)
328 # define GC_ATTR_ALLOC_SIZE(argnum) \
329 __attribute__((__alloc_size__(argnum)))
330 # define GC_ATTR_CALLOC_SIZE(n, s) __attribute__((__alloc_size__(n, s)))
331 # else
332 # define GC_ATTR_ALLOC_SIZE(argnum) /*< empty */
333 # endif
334 # elif GC_GNUC_PREREQ(4, 3) && !defined(__ICC)
335 # define GC_ATTR_ALLOC_SIZE(argnum) \
336 __attribute__((__alloc_size__(argnum)))
337 # define GC_ATTR_CALLOC_SIZE(n, s) __attribute__((__alloc_size__(n, s)))
338 # else
339 # define GC_ATTR_ALLOC_SIZE(argnum) /*< empty */
340 # endif
341 # endif
342
343 # ifndef GC_ATTR_CALLOC_SIZE
344 # define GC_ATTR_CALLOC_SIZE(n, s) /*< empty */
345 # endif
346
347 # ifndef GC_ATTR_NONNULL
348 # if GC_GNUC_PREREQ(4, 0)
349 # define GC_ATTR_NONNULL(argnum) __attribute__((__nonnull__(argnum)))
350 # else
351 # define GC_ATTR_NONNULL(argnum) /*< empty */
352 # endif
353 # endif
354
355 # ifndef GC_ATTR_CONST
356 # if GC_GNUC_PREREQ(4, 0)
357 # define GC_ATTR_CONST __attribute__((__const__))
358 # else
359 # define GC_ATTR_CONST /*< empty */
360 # endif
361 # endif
362
363 # ifndef GC_ATTR_DEPRECATED
364 # ifdef GC_BUILD
365 # undef GC_ATTR_DEPRECATED
366 # define GC_ATTR_DEPRECATED /*< empty */
367 # elif GC_GNUC_PREREQ(4, 0)
368 # define GC_ATTR_DEPRECATED __attribute__((__deprecated__))
369 # elif defined(_MSC_VER) && _MSC_VER >= 1200
370 # define GC_ATTR_DEPRECATED __declspec(deprecated)
371 # else
372 # define GC_ATTR_DEPRECATED /*< empty */
373 # endif
374 # endif
375
376 # ifndef GC_ATTR_NORETURN
377 # if GC_GNUC_PREREQ(2, 7)
378 # define GC_ATTR_NORETURN __attribute__((__noreturn__))
379 # elif defined(_MSC_VER) && _MSC_VER >= 1310 /*< VS 2003+ */
380 # define GC_ATTR_NORETURN __declspec(noreturn)
381 # elif defined(__NORETURN) /*< used in Solaris */
382 # define GC_ATTR_NORETURN __NORETURN
383 # else
384 # define GC_ATTR_NORETURN /*< empty */
385 # endif
386 # endif
387
388 # if defined(__sgi) && !defined(__GNUC__) && _COMPILER_VERSION >= 720
389 # define GC_ADD_CALLER
390 # define GC_RETURN_ADDR ((GC_return_addr_t)__return_address)
391 # endif
392
393 # if defined(__linux__) || defined(__GLIBC__)
394 # if !defined(__native_client__)
395 # include <features.h>
396 # endif
397 # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
398 && !defined(__ia64__) && !defined(GC_MISSING_EXECINFO_H) \
399 && !defined(GC_HAVE_BUILTIN_BACKTRACE)
400 # define GC_HAVE_BUILTIN_BACKTRACE
401 # endif
402 # if defined(__i386__) || defined(__amd64__) || defined(__x86_64__)
403 # define GC_CAN_SAVE_CALL_STACKS
404 # endif
405 # endif /* GLIBC */
406
407 # if defined(_MSC_VER) && (_MSC_VER >= 1200 /* v12.0+ (MSVC 6.0+) */) \
408 && !defined(_M_ARM) && !defined(_M_ARM64) && !defined(_AMD64_) \
409 && !defined(_M_X64) && !defined(_WIN32_WCE) \
410 && !defined(GC_HAVE_NO_BUILTIN_BACKTRACE) \
411 && !defined(GC_HAVE_BUILTIN_BACKTRACE)
412 # define GC_HAVE_BUILTIN_BACKTRACE
413 # endif
414
415 # if defined(GC_HAVE_BUILTIN_BACKTRACE) && !defined(GC_CAN_SAVE_CALL_STACKS) \
416 || defined(__sparc)
417 # define GC_CAN_SAVE_CALL_STACKS
418 # endif
419
420 /*
421 * If we are on a platform on which we cannot save call stacks, but
422 * gcc is normally used, we go ahead and define `GC_ADD_CALLER` macro.
423 * We make this decision independent of whether gcc is actually being
424 * used, in order to keep the interface consistent, and allow mixing
425 * of compilers.
426 * This may also be desirable if it is possible but expensive to
427 * retrieve the call chain.
428 */
429 # if (defined(__linux__) || defined(__DragonFly__) || defined(__FreeBSD__) \
430 || defined(__FreeBSD_kernel__) || defined(__HAIKU__) \
431 || defined(__NetBSD__) || defined(__OpenBSD__) \
432 || defined(HOST_ANDROID) || defined(__ANDROID__)) \
433 && !defined(GC_CAN_SAVE_CALL_STACKS)
434 # define GC_ADD_CALLER
435 # if GC_GNUC_PREREQ(2, 95)
436 /*
437 * gcc knows how to retrieve return address, but we do not know how to
438 * generate call stacks.
439 */
440 # define GC_RETURN_ADDR ((GC_return_addr_t)__builtin_return_address(0))
441 # if GC_GNUC_PREREQ(4, 0) \
442 && (defined(__i386__) || defined(__amd64__) \
443 || defined(__x86_64__) /* and probably others... */) \
444 && !defined(GC_NO_RETURN_ADDR_PARENT)
445 # define GC_HAVE_RETURN_ADDR_PARENT
446 # define GC_RETURN_ADDR_PARENT \
447 ((GC_return_addr_t)__builtin_extract_return_addr( \
448 __builtin_return_address(1)))
449 /*
450 * Note: a compiler might complain that calling `__builtin_return_address`
451 * with a nonzero argument is unsafe.
452 */
453 # endif
454 # else
455 /* Just pass 0 for gcc compatibility. */
456 # define GC_RETURN_ADDR ((GC_return_addr_t)0)
457 # endif
458 # endif /* !GC_CAN_SAVE_CALL_STACKS */
459
460 # ifdef GC_PTHREADS
461
462 # if (defined(GC_DARWIN_THREADS) || defined(GC_WIN32_PTHREADS) \
463 || defined(__native_client__) || defined(GC_RTEMS_PTHREADS)) \
464 && !defined(GC_NO_DLOPEN)
465 /* Either there is no `dlopen()` or we do not need to intercept it. */
466 # define GC_NO_DLOPEN
467 # endif
468
469 # if (defined(GC_DARWIN_THREADS) || defined(GC_WIN32_PTHREADS) \
470 || defined(__native_client__)) \
471 && !defined(GC_NO_PTHREAD_SIGMASK)
472 /* Either there is no `pthread_sigmask()` or no need to intercept it. */
473 # define GC_NO_PTHREAD_SIGMASK
474 # endif
475
476 # if defined(__native_client__)
477 /*
478 * At present, NaCl `pthread_create()` prototype does not have
479 * `const` for its `attr` argument; also, NaCl `pthread_exit()` one
480 * does not have `noreturn` attribute.
481 */
482 # ifndef GC_PTHREAD_CREATE_CONST
483 # define GC_PTHREAD_CREATE_CONST /*< empty */
484 # endif
485 # ifndef GC_HAVE_PTHREAD_EXIT
486 # define GC_HAVE_PTHREAD_EXIT
487 # define GC_PTHREAD_EXIT_ATTRIBUTE /*< empty */
488 # endif
489 # endif
490
491 # if !defined(GC_HAVE_PTHREAD_EXIT) \
492 && ((defined(GC_LINUX_THREADS) && !defined(HOST_ANDROID) \
493 && !defined(__ANDROID__)) \
494 || defined(GC_SOLARIS_THREADS) || defined(__COSMOPOLITAN__))
495 /* Intercept `pthread_exit()` where available and needed. */
496 # define GC_HAVE_PTHREAD_EXIT
497 # define GC_PTHREAD_EXIT_ATTRIBUTE GC_ATTR_NORETURN
498 # endif
499
500 # if (!defined(GC_HAVE_PTHREAD_EXIT) || defined(__native_client__)) \
501 && !defined(GC_NO_PTHREAD_CANCEL)
502 /* Either there is no `pthread_cancel()` or no need to intercept it. */
503 # define GC_NO_PTHREAD_CANCEL
504 # endif
505
506 # endif /* GC_PTHREADS */
507
508 # ifdef __cplusplus
509
510 # ifndef GC_ATTR_EXPLICIT
511 # if __cplusplus >= 201103L && !defined(__clang__) \
512 || _MSVC_LANG >= 201103L || defined(CPPCHECK)
513 # define GC_ATTR_EXPLICIT explicit
514 # else
515 # define GC_ATTR_EXPLICIT /*< empty */
516 # endif
517 # endif
518
519 # ifndef GC_NOEXCEPT
520 # if defined(__DMC__) \
521 || (defined(__BORLANDC__) \
522 && (defined(_RWSTD_NO_EXCEPTIONS) \
523 || defined(_RWSTD_NO_EX_SPEC))) \
524 || (defined(_MSC_VER) && defined(_HAS_EXCEPTIONS) \
525 && !_HAS_EXCEPTIONS) \
526 || (defined(__WATCOMC__) && !defined(_CPPUNWIND))
527 # define GC_NOEXCEPT /*< empty */
528 # ifndef GC_NEW_ABORTS_ON_OOM
529 # define GC_NEW_ABORTS_ON_OOM
530 # endif
531 # elif __cplusplus >= 201103L || _MSVC_LANG >= 201103L
532 # define GC_NOEXCEPT noexcept
533 # else
534 # define GC_NOEXCEPT throw()
535 # endif
536 # endif
537
538 # ifndef GC_CONSTEXPR
539 # if __cplusplus >= 202002L
540 # define GC_CONSTEXPR constexpr
541 # else
542 # define GC_CONSTEXPR /*< empty */
543 # endif
544 # endif
545
546 # endif /* __cplusplus */
547
548 #endif
549