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