gmacros: Don't define bogus __has_* macros

This pollutes the reserved compiler namespace and breaks applications
trying to do their own feature detection. For instance, this falsely
detects that alloca is not a builtin on gcc:

    #include <glib.h>
    #if defined(__has_builtin)
    # if !__has_builtin(alloca)
    #  error "wtf glib?"
    # endif
    #else
    /* version-checking to determine alloca existence */
    #endif

Instead, define our own g_macro__has_* versions that have the
behaviour that we need.

https://bugzilla.gnome.org/show_bug.cgi?id=794635
This commit is contained in:
Nirbheek Chauhan 2018-03-23 23:10:57 +05:30
parent ba4a9538e1
commit e2bd6a6a8f
3 changed files with 31 additions and 14 deletions

View File

@ -108,21 +108,36 @@
#define G_GNUC_NULL_TERMINATED
#endif
/* Clang feature detection: http://clang.llvm.org/docs/LanguageExtensions.html */
#ifndef __has_attribute
#define __has_attribute(x) 0
/*
* Clang feature detection: http://clang.llvm.org/docs/LanguageExtensions.html
* These are not available on GCC, but since the pre-processor doesn't do
* operator short-circuiting, we can't use it in a statement or we'll get:
*
* error: missing binary operator before token "("
*
* So we define it to 0 to satisfy the pre-processor.
*/
#ifdef __has_attribute
#define g_macro__has_attribute __has_attribute
#else
#define g_macro__has_attribute(x) 0
#endif
#ifndef __has_feature
#define __has_feature(x) 0
#ifdef __has_feature
#define g_macro__has_feature __has_feature
#else
#define g_macro__has_feature(x) 0
#endif
#ifndef __has_builtin
#define __has_builtin(x) 0
#ifdef __has_builtin
#define g_macro__has_builtin __has_builtin
#else
#define g_macro__has_builtin(x) 0
#endif
#if (!defined(__clang__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || \
(defined(__clang__) && __has_attribute(__alloc_size__))
(defined(__clang__) && g_macro__has_attribute(__alloc_size__))
#define G_GNUC_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
#define G_GNUC_ALLOC_SIZE2(x,y) __attribute__((__alloc_size__(x,y)))
#else
@ -223,7 +238,7 @@
#endif /* !__GNUC__ */
#endif /* !G_DISABLE_DEPRECATED */
#if __has_feature(attribute_analyzer_noreturn) && defined(__clang_analyzer__)
#if g_macro__has_feature(attribute_analyzer_noreturn) && defined(__clang_analyzer__)
#define G_ANALYZER_ANALYZING 1
#define G_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
#else

View File

@ -250,21 +250,23 @@ template <int w>
#define verify(R) _GL_VERIFY (R, "verify (" #R ")")
#ifndef __has_builtin
# define __has_builtin(x) 0
#ifdef __has_builtin
# define _GL_MACRO__has_builtin __has_builtin
#else
# define _GL_MACRO__has_builtin(x) 0
#endif
/* Assume that R always holds. This lets the compiler optimize
accordingly. R should not have side-effects; it may or may not be
evaluated. Behavior is undefined if R is false. */
#if (__has_builtin (__builtin_unreachable) \
#if (_GL_MACRO__has_builtin (__builtin_unreachable) \
|| 4 < __GNUC__ + (5 <= __GNUC_MINOR__))
# define assume(R) ((R) ? (void) 0 : __builtin_unreachable ())
#elif 1200 <= _MSC_VER
# define assume(R) __assume (R)
#elif (defined lint \
&& (__has_builtin (__builtin_trap) \
&& (_GL_MACRO__has_builtin (__builtin_trap) \
|| 3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__))))
/* Doing it this way helps various packages when configured with
--enable-gcc-warnings, which compiles with -Dlint. It's nicer

View File

@ -384,7 +384,7 @@ typedef const gchar * (*GTranslateFunc) (const gchar *str,
/* https://bugzilla.gnome.org/show_bug.cgi?id=769104 */
#if __GNUC__ >= 5 && !defined(__INTEL_COMPILER)
#define _GLIB_HAVE_BUILTIN_OVERFLOW_CHECKS
#elif __has_builtin(__builtin_uadd_overflow)
#elif g_macro__has_builtin(__builtin_uadd_overflow)
#define _GLIB_HAVE_BUILTIN_OVERFLOW_CHECKS
#endif
#endif