obstack-zprintf: Add more tests.
[gnulib.git] / m4 / extern-inline.m4
blob547da82afa5cb17258a0ebe5c3974406117ed7dd
1 # extern-inline.m4
2 # serial 1
3 dnl Copyright 2012-2024 Free Software Foundation, Inc.
4 dnl This file is free software; the Free Software Foundation
5 dnl gives unlimited permission to copy and/or distribute it,
6 dnl with or without modifications, as long as this notice is preserved.
8 dnl 'extern inline' a la ISO C99.
10 AC_DEFUN([gl_EXTERN_INLINE],
12   AC_CACHE_CHECK([whether ctype.h defines __header_inline],
13     [gl_cv_have___header_inline],
14     [AC_PREPROC_IFELSE(
15        [AC_LANG_SOURCE([[#include <ctype.h>
16                          #ifndef __header_inline
17                           #error "<ctype.h> does not define __header_inline"
18                          #endif
19                         ]])],
20        [gl_cv_have___header_inline=yes],
21        [gl_cv_have___header_inline=no])])
22   if test "$gl_cv_have___header_inline" = yes; then
23     AC_DEFINE([HAVE___HEADER_INLINE], [1],
24       [Define to 1 if ctype.h defines __header_inline.])
25   fi
27   AH_VERBATIM([HAVE___HEADER_INLINE_1],
28 [/* Please see the Gnulib manual for how to use these macros.
30    Suppress extern inline with HP-UX cc, as it appears to be broken; see
31    <https://lists.gnu.org/r/bug-texinfo/2013-02/msg00030.html>.
33    Suppress extern inline with Sun C in standards-conformance mode, as it
34    mishandles inline functions that call each other.  E.g., for 'inline void f
35    (void) { } inline void g (void) { f (); }', c99 incorrectly complains
36    'reference to static identifier "f" in extern inline function'.
37    This bug was observed with Oracle Developer Studio 12.6
38    (Sun C 5.15 SunOS_sparc 2017/05/30).
40    Suppress extern inline (with or without __attribute__ ((__gnu_inline__)))
41    on configurations that mistakenly use 'static inline' to implement
42    functions or macros in standard C headers like <ctype.h>.  For example,
43    if isdigit is mistakenly implemented via a static inline function,
44    a program containing an extern inline function that calls isdigit
45    may not work since the C standard prohibits extern inline functions
46    from calling static functions (ISO C 99 section 6.7.4.(3).
47    This bug is known to occur on:
49      OS X 10.8 and earlier; see:
50      https://lists.gnu.org/r/bug-gnulib/2012-12/msg00023.html
52      DragonFly; see
53      http://muscles.dragonflybsd.org/bulk/clang-master-potential/20141111_102002/logs/ah-tty-0.3.12.log
55      FreeBSD; see:
56      https://lists.gnu.org/r/bug-gnulib/2014-07/msg00104.html
58    OS X 10.9 has a macro __header_inline indicating the bug is fixed for C and
59    for clang but remains for g++; see <https://trac.macports.org/ticket/41033>.
60    Assume DragonFly and FreeBSD will be similar.
62    GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
63    inline semantics, unless -fgnu89-inline is used.  It defines a macro
64    __GNUC_STDC_INLINE__ to indicate this situation or a macro
65    __GNUC_GNU_INLINE__ to indicate the opposite situation.
66    GCC 4.2 with -std=c99 or -std=gnu99 implements the GNU C inline
67    semantics but warns, unless -fgnu89-inline is used:
68      warning: C99 inline functions are not supported; using GNU89
69      warning: to disable this warning use -fgnu89-inline or the gnu_inline function attribute
70    It defines a macro __GNUC_GNU_INLINE__ to indicate this situation.
71  */
72 #if (((defined __APPLE__ && defined __MACH__) \
73       || defined __DragonFly__ || defined __FreeBSD__) \
74      && (defined HAVE___HEADER_INLINE \
75          ? (defined __cplusplus && defined __GNUC_STDC_INLINE__ \
76             && ! defined __clang__) \
77          : ((! defined _DONT_USE_CTYPE_INLINE_ \
78              && (defined __GNUC__ || defined __cplusplus)) \
79             || (defined _FORTIFY_SOURCE && 0 < _FORTIFY_SOURCE \
80                 && defined __GNUC__ && ! defined __cplusplus))))
81 # define _GL_EXTERN_INLINE_STDHEADER_BUG
82 #endif
83 #if ((__GNUC__ \
84       ? (defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ \
85          && !defined __PCC__) \
86       : (199901L <= __STDC_VERSION__ \
87          && !defined __HP_cc \
88          && !defined __PGI \
89          && !(defined __SUNPRO_C && __STDC__))) \
90      && !defined _GL_EXTERN_INLINE_STDHEADER_BUG)
91 # define _GL_INLINE inline
92 # define _GL_EXTERN_INLINE extern inline
93 # define _GL_EXTERN_INLINE_IN_USE
94 #elif (2 < __GNUC__ + (7 <= __GNUC_MINOR__) && !defined __STRICT_ANSI__ \
95        && !defined __PCC__ \
96        && !defined _GL_EXTERN_INLINE_STDHEADER_BUG)
97 # if defined __GNUC_GNU_INLINE__ && __GNUC_GNU_INLINE__
98    /* __gnu_inline__ suppresses a GCC 4.2 diagnostic.  */
99 #  define _GL_INLINE extern inline __attribute__ ((__gnu_inline__))
100 # else
101 #  define _GL_INLINE extern inline
102 # endif
103 # define _GL_EXTERN_INLINE extern
104 # define _GL_EXTERN_INLINE_IN_USE
105 #else
106 # define _GL_INLINE _GL_UNUSED static
107 # define _GL_EXTERN_INLINE _GL_UNUSED static
108 #endif
110 /* In GCC 4.6 (inclusive) to 5.1 (exclusive),
111    suppress bogus "no previous prototype for 'FOO'"
112    and "no previous declaration for 'FOO'" diagnostics,
113    when FOO is an inline function in the header; see
114    <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54113> and
115    <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63877>.  */
116 #if __GNUC__ == 4 && 6 <= __GNUC_MINOR__
117 # if defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__
118 #  define _GL_INLINE_HEADER_CONST_PRAGMA
119 # else
120 #  define _GL_INLINE_HEADER_CONST_PRAGMA \
121      _Pragma ("GCC diagnostic ignored \"-Wsuggest-attribute=const\"")
122 # endif
123 # define _GL_INLINE_HEADER_BEGIN \
124     _Pragma ("GCC diagnostic push") \
125     _Pragma ("GCC diagnostic ignored \"-Wmissing-prototypes\"") \
126     _Pragma ("GCC diagnostic ignored \"-Wmissing-declarations\"") \
127     _GL_INLINE_HEADER_CONST_PRAGMA
128 # define _GL_INLINE_HEADER_END \
129     _Pragma ("GCC diagnostic pop")
130 #else
131 # define _GL_INLINE_HEADER_BEGIN
132 # define _GL_INLINE_HEADER_END
133 #endif])