autoconf: import gcc function attribute check macro
[openafs.git] / src / cf / ax_gcc_func_attribute.m4
1 # ===========================================================================
2 #  https://www.gnu.org/software/autoconf-archive/ax_gcc_func_attribute.html
3 # ===========================================================================
4 #
5 # SYNOPSIS
6 #
7 #   AX_GCC_FUNC_ATTRIBUTE(ATTRIBUTE)
8 #
9 # DESCRIPTION
10 #
11 #   This macro checks if the compiler supports one of GCC's function
12 #   attributes; many other compilers also provide function attributes with
13 #   the same syntax. Compiler warnings are used to detect supported
14 #   attributes as unsupported ones are ignored by default so quieting
15 #   warnings when using this macro will yield false positives.
16 #
17 #   The ATTRIBUTE parameter holds the name of the attribute to be checked.
18 #
19 #   If ATTRIBUTE is supported define HAVE_FUNC_ATTRIBUTE_<ATTRIBUTE>.
20 #
21 #   The macro caches its result in the ax_cv_have_func_attribute_<attribute>
22 #   variable.
23 #
24 #   The macro currently supports the following function attributes:
25 #
26 #    alias
27 #    aligned
28 #    alloc_size
29 #    always_inline
30 #    artificial
31 #    cold
32 #    const
33 #    constructor
34 #    constructor_priority for constructor attribute with priority
35 #    deprecated
36 #    destructor
37 #    dllexport
38 #    dllimport
39 #    error
40 #    externally_visible
41 #    fallthrough
42 #    flatten
43 #    format
44 #    format_arg
45 #    gnu_inline
46 #    hot
47 #    ifunc
48 #    leaf
49 #    malloc
50 #    noclone
51 #    noinline
52 #    nonnull
53 #    noreturn
54 #    nothrow
55 #    optimize
56 #    pure
57 #    sentinel
58 #    sentinel_position
59 #    unused
60 #    used
61 #    visibility
62 #    warning
63 #    warn_unused_result
64 #    weak
65 #    weakref
66 #
67 #   Unsupported function attributes will be tested with a prototype
68 #   returning an int and not accepting any arguments and the result of the
69 #   check might be wrong or meaningless so use with care.
70 #
71 # LICENSE
72 #
73 #   Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com>
74 #
75 #   Copying and distribution of this file, with or without modification, are
76 #   permitted in any medium without royalty provided the copyright notice
77 #   and this notice are preserved.  This file is offered as-is, without any
78 #   warranty.
79
80 #serial 9
81
82 AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [
83     AS_VAR_PUSHDEF([ac_var], [ax_cv_have_func_attribute_$1])
84
85     AC_CACHE_CHECK([for __attribute__(($1))], [ac_var], [
86         AC_LINK_IFELSE([AC_LANG_PROGRAM([
87             m4_case([$1],
88                 [alias], [
89                     int foo( void ) { return 0; }
90                     int bar( void ) __attribute__(($1("foo")));
91                 ],
92                 [aligned], [
93                     int foo( void ) __attribute__(($1(32)));
94                 ],
95                 [alloc_size], [
96                     void *foo(int a) __attribute__(($1(1)));
97                 ],
98                 [always_inline], [
99                     inline __attribute__(($1)) int foo( void ) { return 0; }
100                 ],
101                 [artificial], [
102                     inline __attribute__(($1)) int foo( void ) { return 0; }
103                 ],
104                 [cold], [
105                     int foo( void ) __attribute__(($1));
106                 ],
107                 [const], [
108                     int foo( void ) __attribute__(($1));
109                 ],
110                 [constructor_priority], [
111                     int foo( void ) __attribute__((__constructor__(65535/2)));
112                 ],
113                 [constructor], [
114                     int foo( void ) __attribute__(($1));
115                 ],
116                 [deprecated], [
117                     int foo( void ) __attribute__(($1("")));
118                 ],
119                 [destructor], [
120                     int foo( void ) __attribute__(($1));
121                 ],
122                 [dllexport], [
123                     __attribute__(($1)) int foo( void ) { return 0; }
124                 ],
125                 [dllimport], [
126                     int foo( void ) __attribute__(($1));
127                 ],
128                 [error], [
129                     int foo( void ) __attribute__(($1("")));
130                 ],
131                 [externally_visible], [
132                     int foo( void ) __attribute__(($1));
133                 ],
134                 [fallthrough], [
135                     int foo( void ) {switch (0) { case 1: __attribute__(($1)); case 2: break ; }};
136                 ],
137                 [flatten], [
138                     int foo( void ) __attribute__(($1));
139                 ],
140                 [format], [
141                     int foo(const char *p, ...) __attribute__(($1(printf, 1, 2)));
142                 ],
143                 [format_arg], [
144                     char *foo(const char *p) __attribute__(($1(1)));
145                 ],
146                 [gnu_inline], [
147                     inline __attribute__(($1)) int foo( void ) { return 0; }
148                 ],
149                 [hot], [
150                     int foo( void ) __attribute__(($1));
151                 ],
152                 [ifunc], [
153                     int my_foo( void ) { return 0; }
154                     static int (*resolve_foo(void))(void) { return my_foo; }
155                     int foo( void ) __attribute__(($1("resolve_foo")));
156                 ],
157                 [leaf], [
158                     __attribute__(($1)) int foo( void ) { return 0; }
159                 ],
160                 [malloc], [
161                     void *foo( void ) __attribute__(($1));
162                 ],
163                 [noclone], [
164                     int foo( void ) __attribute__(($1));
165                 ],
166                 [noinline], [
167                     __attribute__(($1)) int foo( void ) { return 0; }
168                 ],
169                 [nonnull], [
170                     int foo(char *p) __attribute__(($1(1)));
171                 ],
172                 [noreturn], [
173                     void foo( void ) __attribute__(($1));
174                 ],
175                 [nothrow], [
176                     int foo( void ) __attribute__(($1));
177                 ],
178                 [optimize], [
179                     __attribute__(($1(3))) int foo( void ) { return 0; }
180                 ],
181                 [pure], [
182                     int foo( void ) __attribute__(($1));
183                 ],
184                 [sentinel], [
185                     int foo(void *p, ...) __attribute__(($1));
186                 ],
187                 [sentinel_position], [
188                     int foo(void *p, ...) __attribute__(($1(1)));
189                 ],
190                 [returns_nonnull], [
191                     void *foo( void ) __attribute__(($1));
192                 ],
193                 [unused], [
194                     int foo( void ) __attribute__(($1));
195                 ],
196                 [used], [
197                     int foo( void ) __attribute__(($1));
198                 ],
199                 [visibility], [
200                     int foo_def( void ) __attribute__(($1("default")));
201                     int foo_hid( void ) __attribute__(($1("hidden")));
202                     int foo_int( void ) __attribute__(($1("internal")));
203                     int foo_pro( void ) __attribute__(($1("protected")));
204                 ],
205                 [warning], [
206                     int foo( void ) __attribute__(($1("")));
207                 ],
208                 [warn_unused_result], [
209                     int foo( void ) __attribute__(($1));
210                 ],
211                 [weak], [
212                     int foo( void ) __attribute__(($1));
213                 ],
214                 [weakref], [
215                     static int foo( void ) { return 0; }
216                     static int bar( void ) __attribute__(($1("foo")));
217                 ],
218                 [
219                  m4_warn([syntax], [Unsupported attribute $1, the test may fail])
220                  int foo( void ) __attribute__(($1));
221                 ]
222             )], [])
223             ],
224             dnl GCC doesn't exit with an error if an unknown attribute is
225             dnl provided but only outputs a warning, so accept the attribute
226             dnl only if no warning were issued.
227             [AS_IF([test -s conftest.err],
228                 [AS_VAR_SET([ac_var], [no])],
229                 [AS_VAR_SET([ac_var], [yes])])],
230             [AS_VAR_SET([ac_var], [no])])
231     ])
232
233     AS_IF([test yes = AS_VAR_GET([ac_var])],
234         [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_FUNC_ATTRIBUTE_$1), 1,
235             [Define to 1 if the system has the `$1' function attribute])], [])
236
237     AS_VAR_POPDEF([ac_var])
238 ])