Commit 882179de authored by Herbert Valerio Riedel's avatar Herbert Valerio Riedel 🕺
Browse files

RTS: Fix & refactor "portable inline" macros

Turns out the current macros for gnu90-style inline
semantics stopped working with GCC 5
(and possibly also with Apple's GCC) which switched on
`__GNUC_STDC_INLINE__` by default falling back to using the
suboptimal `static inline` mode.

However, C99 supports an equivalent (as far as our
use-case is concerned) `extern inline` mode.

See also
for a write-up of gnu90 vs C99 semantics.

This patch also removes the MSVC case as VS2015 is supposed
to finally catch up to C99 (and C11), so we don't need any
special care for MSVC anymore.

Reviewed By: erikd, austin

Differential Revision:
parent 1b4d1201
......@@ -129,51 +129,53 @@
* EXTERN_INLINE is for functions that we want to inline sometimes
* (we also compile a static version of the function; see Inlines.c)
#if defined(__GNUC__) || defined( __INTEL_COMPILER)
# define INLINE_HEADER static inline
# define INLINE_ME inline
// The special "extern inline" behaviour is now only supported by gcc
// when _GNUC_GNU_INLINE__ is defined, and you have to use
// __attribute__((gnu_inline)). So when we don't have this, we use
// ordinary static inline.
// Apple's gcc defines __GNUC_GNU_INLINE__ without providing
// gnu_inline, so we exclude MacOS X and fall through to the safe
// version.
// We generally assume C99 semantics albeit these two definitions work fine even
// when gnu90 semantics are active (i.e. when __GNUC_GNU_INLINE__ is defined or
// when a GCC older than 4.2 is used)
#if defined(__GNUC_GNU_INLINE__) && !defined(__APPLE__)
# if defined(KEEP_INLINES)
# define EXTERN_INLINE inline
# else
# define EXTERN_INLINE extern inline __attribute__((gnu_inline))
# endif
# if defined(KEEP_INLINES)
# else
# endif
// The problem, however, is with 'extern inline' whose semantics significantly
// differs between gnu90 and C99
#define INLINE_HEADER static inline
#define INLINE_ME inline
#define STATIC_INLINE static inline
// Figure out whether `__attributes__((gnu_inline))` is needed
// to force gnu90-style 'external inline' semantics.
#if defined(FORCE_GNU_INLINE)
// disable auto-detection since HAVE_GNU_INLINE has been defined externally
#elif __GNUC_GNU_INLINE__ && __GNUC__ == 4 && __GNUC_MINOR__ == 2
// GCC 4.2.x didn't properly support C99 inline semantics (GCC 4.3 was the first
// release to properly support C99 inline semantics), and therefore warned when
// using 'extern inline' while in C99 mode unless `__attributes__((gnu_inline))`
// was explicitly set.
#elif defined(_MSC_VER)
# define INLINE_HEADER __inline static
# define INLINE_ME __inline
// Force compiler into gnu90 semantics
# if defined(KEEP_INLINES)
# define EXTERN_INLINE __inline
# define EXTERN_INLINE inline __attribute__((gnu_inline))
# else
# define EXTERN_INLINE __inline extern
# define EXTERN_INLINE extern inline __attribute__((gnu_inline))
# endif
// we're currently in gnu90 inline mode by default and
// __attribute__((gnu_inline)) may not be supported, so better leave it off
# if defined(KEEP_INLINES)
# define EXTERN_INLINE inline
# else
# define EXTERN_INLINE extern inline
# endif
# error "Don't know how to inline functions with your C compiler."
// Assume C99 semantics (yes, this curiously results in swapped definitions!)
// This is the preferred branch, and at some point we may drop support for
// compilers not supporting C99 semantics altogether.
# if defined(KEEP_INLINES)
# define EXTERN_INLINE extern inline
# else
# define EXTERN_INLINE inline
# endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment