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 | | ]) |