From 34b0a305f6a86b18ce7c4ca2f9fc71dc89d6e1d4 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 21 May 2019 16:27:17 +0200 Subject: include/c: use __has_attribute The __has macros are more portable (supported by gcc as well as clang). The old __GNUC_PREREQ is deprecated and it should be removed in future. (Well, the __has macros are supported since gcc 5, so we should be patient as some old stable distros (e.g. RHEL 7) use gcc 4.x). This patch helps clang to correctly analyze our xalloc.h stuff. Signed-off-by: Karel Zak --- include/c.h | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'include/c.h') diff --git a/include/c.h b/include/c.h index fc69b910b..02e9e59fa 100644 --- a/include/c.h +++ b/include/c.h @@ -34,7 +34,8 @@ #endif /* - * Compiler-specific stuff + * __GNUC_PREREQ is deprecated in favour of __has_attribute() and + * __has_feature(). The __has macros are supported by clang and gcc>=5. */ #ifndef __GNUC_PREREQ # if defined __GNUC__ && defined __GNUC_MINOR__ @@ -61,11 +62,23 @@ # define ignore_result(x) ((void) (x)) #endif /* !__GNUC__ */ +/* + * It evaluates to 1 if the attribute/feature is supported by the current + * compilation targed. Fallback for old compilers. + */ +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif + +#ifndef __has_feature + #define __has_feature(x) 0 +#endif + /* * Function attributes */ #ifndef __ul_alloc_size -# if __GNUC_PREREQ (4, 3) +# if (__has_attribute(alloc_size) && __has_attribute(warn_unused_result)) || __GNUC_PREREQ (4, 3) # define __ul_alloc_size(s) __attribute__((alloc_size(s), warn_unused_result)) # else # define __ul_alloc_size(s) @@ -73,14 +86,14 @@ #endif #ifndef __ul_calloc_size -# if __GNUC_PREREQ (4, 3) +# if (__has_attribute(alloc_size) && __has_attribute(warn_unused_result)) || __GNUC_PREREQ (4, 3) # define __ul_calloc_size(n, s) __attribute__((alloc_size(n, s), warn_unused_result)) # else # define __ul_calloc_size(n, s) # endif #endif -#if __GNUC_PREREQ (4, 9) +#if __has_attribute(returns_nonnull) || __GNUC_PREREQ (4, 9) # define __ul_returns_nonnull __attribute__((returns_nonnull)) #else # define __ul_returns_nonnull @@ -391,18 +404,12 @@ static inline int xusleep(useconds_t usec) * inlining the function because inlining currently breaks the blacklisting * mechanism of AddressSanitizer. */ -#if defined(__has_feature) -# if __has_feature(address_sanitizer) -# define UL_ASAN_BLACKLIST __attribute__((noinline)) __attribute__((no_sanitize_memory)) __attribute__((no_sanitize_address)) -# else -# define UL_ASAN_BLACKLIST /* nothing */ -# endif +#if __has_feature(address_sanitizer) && __has_attribute(no_sanitize_memory) && __has_attribute(no_sanitize_address) +# define UL_ASAN_BLACKLIST __attribute__((noinline)) __attribute__((no_sanitize_memory)) __attribute__((no_sanitize_address)) #else # define UL_ASAN_BLACKLIST /* nothing */ #endif - - /* * Note that sysconf(_SC_GETPW_R_SIZE_MAX) returns *initial* suggested size for * pwd buffer and in some cases it is not large enough. See POSIX and -- cgit v1.2.3-55-g7522