From 4f98587ff5c6f124aa023e170678bfcd884fe042 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Tue, 7 Mar 2017 18:19:29 +0300 Subject: [PATCH] Define CLANG/GNUC_PREREQ macros to check gcc/clang minimum version (code refactoring) * cord/cordxtra.c (CORD_ATTR_UNUSED): Use GC_GNUC_PREREQ() instead of direct use of __GNUC[_MINOR]__. * gc_cpp.cc (GC_NEW_DELETE_NEED_THROW): Likewise. * include/gc_config_macros.h (GC_API, GC_ATTR_MALLOC, GC_ATTR_ALLOC_SIZE, GC_ATTR_NONNULL, GC_ATTR_DEPRECATED, GC_RETURN_ADDR, GC_RETURN_ADDR_PARENT, GC_PTHREAD_EXIT_ATTRIBUTE): Likewise. * include/gc_cpp.h (GC_NO_OPERATOR_NEW_ARRAY): Likewise. * include/gc_inline.h (GC_EXPECT, GC_PREFETCH_FOR_WRITE): Likewise. * include/new_gc_alloc.h: Likewise. * include/private/gc_priv.h (GC_INNER, GC_ATTR_UNUSED, EXPECT, GC_INLINE, GC_ATTR_NOINLINE, GC_API_OSCALL, GC_ATTR_FORMAT_PRINTF, NONNULL_ARG_NOT_NULL): Likewise. * include/private/gc_priv.h [CANCEL_SAFE] (GC_cancel_disable_count): Likewise. * include/private/gcconfig.h (HAVE_BUILTIN_UNWIND_INIT, PREFETCH, GC_PREFETCH_FOR_WRITE): Likewise. * include/private/gcconfig.h [I386 && LINUX && __ELF__] (GC_NO_SIGSETJMP): Likewise. * include/private/gcconfig.h [X86_64 && MSWIN32] (MPROTECT_VDB): Likewise. * include/private/thread_local_alloc.h [CYGWIN32] (USE_PTHREAD_SPECIFIC): Likewise. * include/private/thread_local_alloc.h [LINUX && !ARM32 && !AVR32 || PLATFORM_ANDROID && !__clang__] (USE_COMPILER_TLS): Likewise. * mark.c [MSWIN32 || MSWINCE] (GC_mark_some): Likewise. * mark_rts.c (GC_approx_sp): Likewise. * tests/test_cpp.cc (ATTR_UNUSED): Likewise. * tools/setjmp_t.c (nested_sp): Likewise. * include/gc_config_macros.h (GC_GNUC_PREREQ): New macro (not for public use). * include/private/gc_priv.h (GC_CLANG_PREREQ): New private macro. * include/private/gcconfig.h (HAVE_BUILTIN_UNWIND_INIT): Refine comment. * include/private/thread_local_alloc.h [LINUX && !ARM32 && !AVR32 || PLATFORM_ANDROID && !__clang__] (USE_COMPILER_TLS): Use GC_CLANG_PREREQ() instead of direct use of __clang_major__ and __clang_minor__. * mark.c [MSWIN32 || MSWINCE] (GC_mark_some): Likewise. --- cord/cordxtra.c | 2 +- gc_cpp.cc | 3 +-- include/gc_config_macros.h | 28 ++++++++++++++++----------- include/gc_cpp.h | 3 +-- include/gc_inline.h | 6 +++--- include/new_gc_alloc.h | 19 +++++++++--------- include/private/gc_priv.h | 29 +++++++++++++++++----------- include/private/gcconfig.h | 19 ++++++++---------- include/private/thread_local_alloc.h | 7 +++---- mark.c | 4 +--- mark_rts.c | 2 +- tests/test_cpp.cc | 2 +- tools/setjmp_t.c | 2 +- 13 files changed, 65 insertions(+), 61 deletions(-) diff --git a/cord/cordxtra.c b/cord/cordxtra.c index cac407d4..61df89b4 100644 --- a/cord/cordxtra.c +++ b/cord/cordxtra.c @@ -63,7 +63,7 @@ typedef void (* oom_fn)(void); ABORT("Out of memory"); } # define ABORT(msg) { fprintf(stderr, "%s\n", msg); abort(); } -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +#if GC_GNUC_PREREQ(3, 4) # define CORD_ATTR_UNUSED __attribute__((__unused__)) #else # define CORD_ATTR_UNUSED /* empty */ diff --git a/gc_cpp.cc b/gc_cpp.cc index 185ec25a..04737dce 100644 --- a/gc_cpp.cc +++ b/gc_cpp.cc @@ -29,8 +29,7 @@ built-in "new" and "delete". #include "gc_cpp.h" -#if !defined(GC_NEW_DELETE_NEED_THROW) && defined(__GNUC__) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) +#if GC_GNUC_PREREQ(4, 2) && !defined(GC_NEW_DELETE_NEED_THROW) # define GC_NEW_DELETE_NEED_THROW #endif diff --git a/include/gc_config_macros.h b/include/gc_config_macros.h index e8748f5d..df63c9c0 100644 --- a/include/gc_config_macros.h +++ b/include/gc_config_macros.h @@ -19,6 +19,14 @@ /* We separate it only to make gc.h more suitable as documentation. */ #if defined(GC_H) +/* Convenient internal macro to test version of GCC. */ +#if defined(__GNUC__) && defined(__GNUC_MINOR__) +# define GC_GNUC_PREREQ(major, minor) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((major) << 16) + (minor)) +#else +# define GC_GNUC_PREREQ(major, minor) 0 /* FALSE */ +#endif + /* Some tests for old macros. These violate our namespace rules and */ /* will disappear shortly. Use the GC_ names. */ #if defined(SOLARIS_THREADS) || defined(_SOLARIS_THREADS) \ @@ -204,7 +212,7 @@ # elif defined(__GNUC__) /* Only matters if used in conjunction with -fvisibility=hidden option. */ # if defined(GC_BUILD) && !defined(GC_NO_VISIBILITY) \ - && (__GNUC__ >= 4 || defined(GC_VISIBILITY_HIDDEN_SET)) + && (GC_GNUC_PREREQ(4, 0) || defined(GC_VISIBILITY_HIDDEN_SET)) # define GC_API extern __attribute__((__visibility__("default"))) # endif # endif @@ -230,8 +238,7 @@ /* by using custom GC_oom_func then define GC_OOM_FUNC_RETURNS_ALIAS. */ # ifdef GC_OOM_FUNC_RETURNS_ALIAS # define GC_ATTR_MALLOC /* empty */ -# elif defined(__GNUC__) && (__GNUC__ > 3 \ - || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +# elif GC_GNUC_PREREQ(3, 1) # define GC_ATTR_MALLOC __attribute__((__malloc__)) # elif defined(_MSC_VER) && _MSC_VER >= 1400 # define GC_ATTR_MALLOC __declspec(noalias) __declspec(restrict) @@ -249,8 +256,7 @@ # else # define GC_ATTR_ALLOC_SIZE(argnum) /* empty */ # endif -# elif __GNUC__ > 4 \ - || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 && !defined(__ICC)) +# elif GC_GNUC_PREREQ(4, 3) && !defined(__ICC) # define GC_ATTR_ALLOC_SIZE(argnum) __attribute__((__alloc_size__(argnum))) # else # define GC_ATTR_ALLOC_SIZE(argnum) /* empty */ @@ -258,7 +264,7 @@ #endif #ifndef GC_ATTR_NONNULL -# if defined(__GNUC__) && __GNUC__ >= 4 +# if GC_GNUC_PREREQ(4, 0) # define GC_ATTR_NONNULL(argnum) __attribute__((__nonnull__(argnum))) # else # define GC_ATTR_NONNULL(argnum) /* empty */ @@ -269,7 +275,7 @@ # ifdef GC_BUILD # undef GC_ATTR_DEPRECATED # define GC_ATTR_DEPRECATED /* empty */ -# elif defined(__GNUC__) && __GNUC__ >= 4 +# elif GC_GNUC_PREREQ(4, 0) # define GC_ATTR_DEPRECATED __attribute__((__deprecated__)) # elif defined(_MSC_VER) && _MSC_VER >= 1200 # define GC_ATTR_DEPRECATED __declspec(deprecated) @@ -325,12 +331,12 @@ || defined(PLATFORM_ANDROID) || defined(__ANDROID__)) \ && !defined(GC_CAN_SAVE_CALL_STACKS) # define GC_ADD_CALLER -# if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +# if GC_GNUC_PREREQ(2, 95) /* gcc knows how to retrieve return address, but we don't know */ /* how to generate call stacks. */ # define GC_RETURN_ADDR (GC_word)__builtin_return_address(0) -# if (__GNUC__ >= 4) && (defined(__i386__) || defined(__amd64__) \ - || defined(__x86_64__) /* and probably others... */) +# if GC_GNUC_PREREQ(4, 0) && (defined(__i386__) || defined(__amd64__) \ + || defined(__x86_64__) /* and probably others... */) # define GC_HAVE_RETURN_ADDR_PARENT # define GC_RETURN_ADDR_PARENT \ (GC_word)__builtin_extract_return_addr(__builtin_return_address(1)) @@ -375,7 +381,7 @@ && (defined(GC_LINUX_THREADS) || defined(GC_SOLARIS_THREADS)) # define GC_HAVE_PTHREAD_EXIT /* Intercept pthread_exit on Linux and Solaris. */ -# if defined(__GNUC__) /* since GCC v2.7 */ +# if GC_GNUC_PREREQ(2, 7) # define GC_PTHREAD_EXIT_ATTRIBUTE __attribute__((__noreturn__)) # elif defined(__NORETURN) /* used in Solaris */ # define GC_PTHREAD_EXIT_ATTRIBUTE __NORETURN diff --git a/include/gc_cpp.h b/include/gc_cpp.h index 1ed36be5..920b8368 100644 --- a/include/gc_cpp.h +++ b/include/gc_cpp.h @@ -157,8 +157,7 @@ by UseGC. GC is an alias for UseGC, unless GC_NAME_CONFLICT is defined. #if !defined(GC_NO_OPERATOR_NEW_ARRAY) \ && !defined(_ENABLE_ARRAYNEW) /* Digimars */ \ && (defined(__BORLANDC__) && (__BORLANDC__ < 0x450) \ - || (defined(__GNUC__) && \ - (__GNUC__ < 2 || __GNUC__ == 2 && __GNUC_MINOR__ < 6)) \ + || (defined(__GNUC__) && !GC_GNUC_PREREQ(2, 6)) \ || (defined(_MSC_VER) && _MSC_VER <= 1020) \ || (defined(__WATCOMC__) && __WATCOMC__ < 1050)) # define GC_NO_OPERATOR_NEW_ARRAY diff --git a/include/gc_inline.h b/include/gc_inline.h index f0d81897..45281c9d 100644 --- a/include/gc_inline.h +++ b/include/gc_inline.h @@ -31,12 +31,12 @@ #include "gc.h" #include "gc_tiny_fl.h" -#if __GNUC__ >= 3 +#if GC_GNUC_PREREQ(3, 0) # define GC_EXPECT(expr, outcome) __builtin_expect(expr,outcome) /* Equivalent to (expr), but predict that usually (expr)==outcome. */ #else # define GC_EXPECT(expr, outcome) (expr) -#endif /* __GNUC__ */ +#endif #ifndef GC_ASSERT # ifdef NDEBUG @@ -48,7 +48,7 @@ #endif #ifndef GC_PREFETCH_FOR_WRITE -# if defined(__GNUC__) && __GNUC__ >= 3 && !defined(GC_NO_PREFETCH_FOR_WRITE) +# if GC_GNUC_PREREQ(3, 0) && !defined(GC_NO_PREFETCH_FOR_WRITE) # define GC_PREFETCH_FOR_WRITE(x) __builtin_prefetch((x), 1) # else # define GC_PREFETCH_FOR_WRITE(x) (void)0 diff --git a/include/new_gc_alloc.h b/include/new_gc_alloc.h index fc79b5b0..cd7ee5d5 100644 --- a/include/new_gc_alloc.h +++ b/include/new_gc_alloc.h @@ -48,23 +48,22 @@ #include "gc.h" -#if (__GNUC__ < 3) -# include // A more portable way to get stl_alloc.h . -#else +#if GC_GNUC_PREREQ(3, 0) # include # ifndef __STL_BEGIN_NAMESPACE -# define __STL_BEGIN_NAMESPACE namespace std { -# define __STL_END_NAMESPACE }; +# define __STL_BEGIN_NAMESPACE namespace std { +# define __STL_END_NAMESPACE }; # endif -#ifndef __STL_USE_STD_ALLOCATORS -#define __STL_USE_STD_ALLOCATORS -#endif +# ifndef __STL_USE_STD_ALLOCATORS +# define __STL_USE_STD_ALLOCATORS +# endif +#else +# include // A more portable way to get stl_alloc.h file. #endif /* A hack to deal with gcc 3.1. If you are using gcc3.1 and later, */ /* you should probably really use gc_allocator.h instead. */ -#if defined (__GNUC__) && \ - (__GNUC__ > 3 || (__GNUC__ == 3 && (__GNUC_MINOR__ >= 1))) +#if GC_GNUC_PREREQ(3, 1) # define simple_alloc __simple_alloc #endif diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index cbaeb374..02014477 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -70,6 +70,14 @@ # endif #endif +/* Convenient internal macro to test version of Clang. */ +#if defined(__clang__) && defined(__clang_major__) +# define GC_CLANG_PREREQ(major, minor) \ + ((__clang_major__ << 16) + __clang_minor__ >= ((major) << 16) + (minor)) +#else +# define GC_CLANG_PREREQ(major, minor) 0 /* FALSE */ +#endif + #ifndef GC_TINY_FL_H # include "../gc_tiny_fl.h" #endif @@ -123,7 +131,7 @@ typedef char * ptr_t; /* A generic pointer to which we can add */ /* located in the "extra" folder). */ # if defined(GC_DLL) && defined(__GNUC__) && !defined(MSWIN32) \ && !defined(MSWINCE) && !defined(CYGWIN32) -# if (__GNUC__ >= 4) && !defined(GC_NO_VISIBILITY) +# if GC_GNUC_PREREQ(4, 0) && !defined(GC_NO_VISIBILITY) /* See the corresponding GC_API definition. */ # define GC_INNER __attribute__((__visibility__("hidden"))) # else @@ -165,14 +173,14 @@ typedef char * ptr_t; /* A generic pointer to which we can add */ #endif /* !GC_ATTR_NO_SANITIZE_MEMORY */ #ifndef GC_ATTR_UNUSED -# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +# if GC_GNUC_PREREQ(3, 4) # define GC_ATTR_UNUSED __attribute__((__unused__)) # else # define GC_ATTR_UNUSED /* empty */ # endif #endif /* !GC_ATTR_UNUSED */ -#if __GNUC__ >= 3 && !defined(LINT2) +#if GC_GNUC_PREREQ(3, 0) && !defined(LINT2) # define EXPECT(expr, outcome) __builtin_expect(expr,outcome) /* Equivalent to (expr), but predict that usually (expr)==outcome. */ #else @@ -183,17 +191,17 @@ typedef char * ptr_t; /* A generic pointer to which we can add */ /* The "inline" keyword is determined by Autoconf AC_C_INLINE. */ # define GC_INLINE static inline #elif defined(_MSC_VER) || defined(__INTEL_COMPILER) || defined(__DMC__) \ - || ((__GNUC__ >= 3) && defined(__STRICT_ANSI__)) \ + || (GC_GNUC_PREREQ(3, 0) && defined(__STRICT_ANSI__)) \ || defined(__WATCOMC__) # define GC_INLINE static __inline -#elif (__GNUC__ >= 3) || defined(__sun) +#elif GC_GNUC_PREREQ(3, 0) || defined(__sun) # define GC_INLINE static inline #else # define GC_INLINE static #endif #ifndef GC_ATTR_NOINLINE -# if __GNUC__ >= 4 +# if GC_GNUC_PREREQ(4, 0) # define GC_ATTR_NOINLINE __attribute__((__noinline__)) # elif _MSC_VER >= 1400 # define GC_ATTR_NOINLINE __declspec(noinline) @@ -205,7 +213,7 @@ typedef char * ptr_t; /* A generic pointer to which we can add */ #ifndef GC_API_OSCALL /* This is used to identify GC routines called by name from OS. */ # if defined(__GNUC__) -# if (__GNUC__ >= 4) && !defined(GC_NO_VISIBILITY) +# if GC_GNUC_PREREQ(4, 0) && !defined(GC_NO_VISIBILITY) /* Same as GC_API if GC_DLL. */ # define GC_API_OSCALL extern __attribute__((__visibility__("default"))) # else @@ -2173,7 +2181,7 @@ void GC_noop6(word, word, word, word, word, word); GC_API void GC_CALL GC_noop1(word); #ifndef GC_ATTR_FORMAT_PRINTF -# if defined(__GNUC__) && __GNUC__ >= 3 +# if GC_GNUC_PREREQ(3, 0) # define GC_ATTR_FORMAT_PRINTF(spec_argnum, first_checked) \ __attribute__((__format__(__printf__, spec_argnum, first_checked))) # else @@ -2431,7 +2439,7 @@ GC_INNER ptr_t GC_store_debug_info(ptr_t p, word sz, const char *str, #endif /* Runtime check for an argument declared as non-null is actually not null. */ -#if defined(__GNUC__) && __GNUC__ >= 4 +#if GC_GNUC_PREREQ(4, 0) /* Workaround tautological-pointer-compare Clang warning. */ # define NONNULL_ARG_NOT_NULL(arg) (*(volatile void **)&(arg) != NULL) #else @@ -2603,8 +2611,7 @@ GC_INNER ptr_t GC_store_debug_info(ptr_t p, word sz, const char *str, /* Some convenience macros for cancellation support. */ #if defined(CANCEL_SAFE) # if defined(GC_ASSERTIONS) && (defined(USE_COMPILER_TLS) \ - || (defined(LINUX) && !defined(ARM32) \ - && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) \ + || (defined(LINUX) && !defined(ARM32) && GC_GNUC_PREREQ(3, 3)) \ || defined(HPUX) /* and probably others ... */)) extern __thread unsigned char GC_cancel_disable_count; # define NEED_CANCEL_DISABLE_COUNT diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h index 6016b471..3364acfe 100644 --- a/include/private/gcconfig.h +++ b/include/private/gcconfig.h @@ -768,10 +768,9 @@ * allocation. */ -/* If we are using a recent version of gcc, we can use */ -/* __builtin_unwind_init() to push the relevant registers onto the stack. */ -# if defined(__GNUC__) && ((__GNUC__ >= 3) \ - || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)) \ +/* If available, we can use __builtin_unwind_init() to push the */ +/* relevant registers onto the stack. */ +# if GC_GNUC_PREREQ(2, 8) \ && !defined(__INTEL_COMPILER) && !defined(__PATHCC__) \ && !defined(__FUJITSU) /* for FX10 system */ \ && !(defined(POWERPC) && defined(DARWIN)) /* for MacOS X 10.3.9 */ \ @@ -1385,10 +1384,8 @@ extern int _end[]; # define DATAEND ((ptr_t)(_end)) # if defined(PLATFORM_ANDROID) && !defined(GC_NO_SIGSETJMP) \ - && !(__ANDROID_API__ >= 18 || __GNUC__ > 4 \ - || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) \ - || __clang_major__ > 3 \ - || (__clang_major__ == 3 && __clang_minor__ >= 2)) + && !(GC_GNUC_PREREQ(4, 8) || GC_CLANG_PREREQ(3, 2) \ + || __ANDROID_API__ >= 18) /* Older Android NDK releases lack sigsetjmp in x86 libc */ /* (setjmp is used instead to find data_start). The bug */ /* is fixed in Android NDK r8e (so, ok to use sigsetjmp */ @@ -2549,7 +2546,7 @@ /* STACKBOTTOM and DATASTART are handled specially in */ /* os_dep.c. */ # if !defined(__GNUC__) || defined(__INTEL_COMPILER) \ - || __GNUC__ >= 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) + || GC_GNUC_PREREQ(4, 7) /* Older GCC has not supported SetUnhandledExceptionFilter */ /* properly on x64 (e.g. SEH unwinding information missed). */ # define MPROTECT_VDB @@ -2892,7 +2889,7 @@ #endif #ifndef PREFETCH -# if defined(__GNUC__) && __GNUC__ >= 3 && !defined(NO_PREFETCH) +# if GC_GNUC_PREREQ(3, 0) && !defined(NO_PREFETCH) # define PREFETCH(x) __builtin_prefetch((x), 0, 0) # else # define PREFETCH(x) (void)0 @@ -2900,7 +2897,7 @@ #endif #ifndef GC_PREFETCH_FOR_WRITE -# if defined(__GNUC__) && __GNUC__ >= 3 && !defined(GC_NO_PREFETCH_FOR_WRITE) +# if GC_GNUC_PREREQ(3, 0) && !defined(GC_NO_PREFETCH_FOR_WRITE) # define GC_PREFETCH_FOR_WRITE(x) __builtin_prefetch((x), 1) # else # define GC_PREFETCH_FOR_WRITE(x) (void)0 diff --git a/include/private/thread_local_alloc.h b/include/private/thread_local_alloc.h index 3b44a1e6..5b9bec37 100644 --- a/include/private/thread_local_alloc.h +++ b/include/private/thread_local_alloc.h @@ -36,7 +36,7 @@ && !defined(USE_WIN32_COMPILER_TLS) && !defined(USE_COMPILER_TLS) \ && !defined(USE_CUSTOM_SPECIFIC) # if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32) -# if defined(CYGWIN32) && (__GNUC__ >= 4) +# if defined(CYGWIN32) && GC_GNUC_PREREQ(4, 0) # if defined(__clang__) /* As of Cygwin clang3.5.2, thread-local storage is unsupported. */ # define USE_PTHREAD_SPECIFIC @@ -49,11 +49,10 @@ # define USE_WIN32_COMPILER_TLS # endif /* !GNU */ # elif (defined(LINUX) && !defined(ARM32) && !defined(AVR32) \ - && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) \ + && GC_GNUC_PREREQ(3, 3) \ && !(defined(__clang__) && defined(PLATFORM_ANDROID))) \ || (defined(PLATFORM_ANDROID) && !defined(__clang__) \ - && defined(ARM32) \ - && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))) + && defined(ARM32) && GC_GNUC_PREREQ(4, 6)) /* As of Android NDK r10e, Clang cannot find __tls_get_addr. */ # define USE_COMPILER_TLS # elif defined(GC_DGUX386_THREADS) || defined(GC_OSF1_THREADS) \ diff --git a/mark.c b/mark.c index 9b1d0fed..d5682134 100644 --- a/mark.c +++ b/mark.c @@ -531,9 +531,7 @@ static void alloc_mark_stack(size_t); ext_ex_regn er; -# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) \ - || __clang_major__ > 3 \ - || (__clang_major__ == 3 && __clang_minor__ >= 3) +# if GC_GNUC_PREREQ(4, 7) || GC_CLANG_PREREQ(3, 3) # pragma GCC diagnostic push /* Suppress "taking the address of label is non-standard" warning. */ # if defined(__clang__) diff --git a/mark_rts.c b/mark_rts.c index a06ce89c..eb2e0e92 100644 --- a/mark_rts.c +++ b/mark_rts.c @@ -391,7 +391,7 @@ STATIC void GC_remove_tmp_roots(void) GC_INNER ptr_t GC_approx_sp(void) { volatile word sp; -# if defined(__GNUC__) && (__GNUC__ >= 4) +# if GC_GNUC_PREREQ(4, 0) sp = (word)__builtin_frame_address(0); # else sp = (word)&sp; diff --git a/tests/test_cpp.cc b/tests/test_cpp.cc index 1a6c5b64..3d6be9a8 100644 --- a/tests/test_cpp.cc +++ b/tests/test_cpp.cc @@ -70,7 +70,7 @@ extern "C" { __LINE__ ); \ exit( 1 ); } -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +#if GC_GNUC_PREREQ(3, 4) # define ATTR_UNUSED __attribute__((__unused__)) #else # define ATTR_UNUSED /* empty */ diff --git a/tools/setjmp_t.c b/tools/setjmp_t.c index 99f1f7d7..987599ed 100644 --- a/tools/setjmp_t.c +++ b/tools/setjmp_t.c @@ -62,7 +62,7 @@ struct { word nested_sp(void) { -# if defined(__GNUC__) && (__GNUC__ >= 4) +# if GC_GNUC_PREREQ(4, 0) return (word)__builtin_frame_address(0); # else volatile word sp; -- 2.40.0