extern-inline.m4 4.87 KB
Newer Older
1 2
dnl 'extern inline' a la ISO C99.

Paul Eggert's avatar
Paul Eggert committed
3
dnl Copyright 2012-2019 Free Software Foundation, Inc.
4 5 6 7 8 9 10
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.

AC_DEFUN([gl_EXTERN_INLINE],
[
  AH_VERBATIM([extern_inline],
11
[/* Please see the Gnulib manual for how to use these macros.
12

Paul Eggert's avatar
Paul Eggert committed
13
   Suppress extern inline with HP-UX cc, as it appears to be broken; see
Paul Eggert's avatar
Paul Eggert committed
14
   <https://lists.gnu.org/r/bug-texinfo/2013-02/msg00030.html>.
Paul Eggert's avatar
Paul Eggert committed
15

Paul Eggert's avatar
Paul Eggert committed
16 17 18 19 20 21
   Suppress extern inline with Sun C in standards-conformance mode, as it
   mishandles inline functions that call each other.  E.g., for 'inline void f
   (void) { } inline void g (void) { f (); }', c99 incorrectly complains
   'reference to static identifier "f" in extern inline function'.
   This bug was observed with Sun C 5.12 SunOS_i386 2011/11/16.

22 23 24 25 26 27
   Suppress extern inline (with or without __attribute__ ((__gnu_inline__)))
   on configurations that mistakenly use 'static inline' to implement
   functions or macros in standard C headers like <ctype.h>.  For example,
   if isdigit is mistakenly implemented via a static inline function,
   a program containing an extern inline function that calls isdigit
   may not work since the C standard prohibits extern inline functions
Paul Eggert's avatar
Paul Eggert committed
28 29
   from calling static functions (ISO C 99 section 6.7.4.(3).
   This bug is known to occur on:
30 31

     OS X 10.8 and earlier; see:
Paul Eggert's avatar
Paul Eggert committed
32
     https://lists.gnu.org/r/bug-gnulib/2012-12/msg00023.html
33 34 35 36 37

     DragonFly; see
     http://muscles.dragonflybsd.org/bulk/bleeding-edge-potential/latest-per-pkg/ah-tty-0.3.12.log

     FreeBSD; see:
Paul Eggert's avatar
Paul Eggert committed
38
     https://lists.gnu.org/r/bug-gnulib/2014-07/msg00104.html
39

Paul Eggert's avatar
Paul Eggert committed
40
   OS X 10.9 has a macro __header_inline indicating the bug is fixed for C and
Paul Eggert's avatar
Paul Eggert committed
41
   for clang but remains for g++; see <https://trac.macports.org/ticket/41033>.
Paul Eggert's avatar
Paul Eggert committed
42 43 44 45 46 47 48 49 50 51 52 53
   Assume DragonFly and FreeBSD will be similar.

   GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
   inline semantics, unless -fgnu89-inline is used.  It defines a macro
   __GNUC_STDC_INLINE__ to indicate this situation or a macro
   __GNUC_GNU_INLINE__ to indicate the opposite situation.
   GCC 4.2 with -std=c99 or -std=gnu99 implements the GNU C inline
   semantics but warns, unless -fgnu89-inline is used:
     warning: C99 inline functions are not supported; using GNU89
     warning: to disable this warning use -fgnu89-inline or the gnu_inline function attribute
   It defines a macro __GNUC_GNU_INLINE__ to indicate this situation.
 */
54 55
#if (((defined __APPLE__ && defined __MACH__) \
      || defined __DragonFly__ || defined __FreeBSD__) \
Paul Eggert's avatar
Paul Eggert committed
56 57 58 59 60 61 62
     && (defined __header_inline \
         ? (defined __cplusplus && defined __GNUC_STDC_INLINE__ \
            && ! defined __clang__) \
         : ((! defined _DONT_USE_CTYPE_INLINE_ \
             && (defined __GNUC__ || defined __cplusplus)) \
            || (defined _FORTIFY_SOURCE && 0 < _FORTIFY_SOURCE \
                && defined __GNUC__ && ! defined __cplusplus))))
63
# define _GL_EXTERN_INLINE_STDHEADER_BUG
Paul Eggert's avatar
Paul Eggert committed
64
#endif
65 66
#if ((__GNUC__ \
      ? defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ \
Paul Eggert's avatar
Paul Eggert committed
67 68
      : (199901L <= __STDC_VERSION__ \
         && !defined __HP_cc \
Paul Eggert's avatar
Paul Eggert committed
69
         && !defined __PGI \
Paul Eggert's avatar
Paul Eggert committed
70
         && !(defined __SUNPRO_C && __STDC__))) \
71
     && !defined _GL_EXTERN_INLINE_STDHEADER_BUG)
72 73
# define _GL_INLINE inline
# define _GL_EXTERN_INLINE extern inline
Paul Eggert's avatar
Paul Eggert committed
74
# define _GL_EXTERN_INLINE_IN_USE
Paul Eggert's avatar
Paul Eggert committed
75
#elif (2 < __GNUC__ + (7 <= __GNUC_MINOR__) && !defined __STRICT_ANSI__ \
76
       && !defined _GL_EXTERN_INLINE_STDHEADER_BUG)
Paul Eggert's avatar
Paul Eggert committed
77
# if defined __GNUC_GNU_INLINE__ && __GNUC_GNU_INLINE__
Paul Eggert's avatar
Paul Eggert committed
78 79 80 81
   /* __gnu_inline__ suppresses a GCC 4.2 diagnostic.  */
#  define _GL_INLINE extern inline __attribute__ ((__gnu_inline__))
# else
#  define _GL_INLINE extern inline
82
# endif
Paul Eggert's avatar
Paul Eggert committed
83
# define _GL_EXTERN_INLINE extern
Paul Eggert's avatar
Paul Eggert committed
84
# define _GL_EXTERN_INLINE_IN_USE
85
#else
86 87
# define _GL_INLINE static _GL_UNUSED
# define _GL_EXTERN_INLINE static _GL_UNUSED
88 89
#endif

Paul Eggert's avatar
Paul Eggert committed
90 91
/* In GCC 4.6 (inclusive) to 5.1 (exclusive),
   suppress bogus "no previous prototype for 'FOO'"
Paul Eggert's avatar
Paul Eggert committed
92 93 94 95
   and "no previous declaration for 'FOO'" diagnostics,
   when FOO is an inline function in the header; see
   <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54113> and
   <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63877>.  */
Paul Eggert's avatar
Paul Eggert committed
96
#if __GNUC__ == 4 && 6 <= __GNUC_MINOR__
Paul Eggert's avatar
Paul Eggert committed
97
# if defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__
Paul Eggert's avatar
Paul Eggert committed
98 99 100 101 102 103 104 105 106 107 108 109 110
#  define _GL_INLINE_HEADER_CONST_PRAGMA
# else
#  define _GL_INLINE_HEADER_CONST_PRAGMA \
     _Pragma ("GCC diagnostic ignored \"-Wsuggest-attribute=const\"")
# endif
# define _GL_INLINE_HEADER_BEGIN \
    _Pragma ("GCC diagnostic push") \
    _Pragma ("GCC diagnostic ignored \"-Wmissing-prototypes\"") \
    _Pragma ("GCC diagnostic ignored \"-Wmissing-declarations\"") \
    _GL_INLINE_HEADER_CONST_PRAGMA
# define _GL_INLINE_HEADER_END \
    _Pragma ("GCC diagnostic pop")
#else
111 112 113 114
# define _GL_INLINE_HEADER_BEGIN
# define _GL_INLINE_HEADER_END
#endif])
])