ax_gcc_func_attribute.m4 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  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. #serial 9
  80. AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [
  81. AS_VAR_PUSHDEF([ac_var], [ax_cv_have_func_attribute_$1])
  82. AC_CACHE_CHECK([for __attribute__(($1))], [ac_var], [
  83. AC_LINK_IFELSE([AC_LANG_PROGRAM([
  84. m4_case([$1],
  85. [alias], [
  86. int foo( void ) { return 0; }
  87. int bar( void ) __attribute__(($1("foo")));
  88. ],
  89. [aligned], [
  90. int foo( void ) __attribute__(($1(32)));
  91. ],
  92. [alloc_size], [
  93. void *foo(int a) __attribute__(($1(1)));
  94. ],
  95. [always_inline], [
  96. inline __attribute__(($1)) int foo( void ) { return 0; }
  97. ],
  98. [artificial], [
  99. inline __attribute__(($1)) int foo( void ) { return 0; }
  100. ],
  101. [cold], [
  102. int foo( void ) __attribute__(($1));
  103. ],
  104. [const], [
  105. int foo( void ) __attribute__(($1));
  106. ],
  107. [constructor_priority], [
  108. int foo( void ) __attribute__((__constructor__(65535/2)));
  109. ],
  110. [constructor], [
  111. int foo( void ) __attribute__(($1));
  112. ],
  113. [deprecated], [
  114. int foo( void ) __attribute__(($1("")));
  115. ],
  116. [destructor], [
  117. int foo( void ) __attribute__(($1));
  118. ],
  119. [dllexport], [
  120. __attribute__(($1)) int foo( void ) { return 0; }
  121. ],
  122. [dllimport], [
  123. int foo( void ) __attribute__(($1));
  124. ],
  125. [error], [
  126. int foo( void ) __attribute__(($1("")));
  127. ],
  128. [externally_visible], [
  129. int foo( void ) __attribute__(($1));
  130. ],
  131. [fallthrough], [
  132. int foo( void ) {switch (0) { case 1: __attribute__(($1)); case 2: break ; }};
  133. ],
  134. [flatten], [
  135. int foo( void ) __attribute__(($1));
  136. ],
  137. [format], [
  138. int foo(const char *p, ...) __attribute__(($1(printf, 1, 2)));
  139. ],
  140. [format_arg], [
  141. char *foo(const char *p) __attribute__(($1(1)));
  142. ],
  143. [gnu_inline], [
  144. inline __attribute__(($1)) int foo( void ) { return 0; }
  145. ],
  146. [hot], [
  147. int foo( void ) __attribute__(($1));
  148. ],
  149. [ifunc], [
  150. int my_foo( void ) { return 0; }
  151. static int (*resolve_foo(void))(void) { return my_foo; }
  152. int foo( void ) __attribute__(($1("resolve_foo")));
  153. ],
  154. [leaf], [
  155. __attribute__(($1)) int foo( void ) { return 0; }
  156. ],
  157. [malloc], [
  158. void *foo( void ) __attribute__(($1));
  159. ],
  160. [noclone], [
  161. int foo( void ) __attribute__(($1));
  162. ],
  163. [noinline], [
  164. __attribute__(($1)) int foo( void ) { return 0; }
  165. ],
  166. [nonnull], [
  167. int foo(char *p) __attribute__(($1(1)));
  168. ],
  169. [noreturn], [
  170. void foo( void ) __attribute__(($1));
  171. ],
  172. [nothrow], [
  173. int foo( void ) __attribute__(($1));
  174. ],
  175. [optimize], [
  176. __attribute__(($1(3))) int foo( void ) { return 0; }
  177. ],
  178. [pure], [
  179. int foo( void ) __attribute__(($1));
  180. ],
  181. [sentinel], [
  182. int foo(void *p, ...) __attribute__(($1));
  183. ],
  184. [sentinel_position], [
  185. int foo(void *p, ...) __attribute__(($1(1)));
  186. ],
  187. [returns_nonnull], [
  188. void *foo( void ) __attribute__(($1));
  189. ],
  190. [unused], [
  191. int foo( void ) __attribute__(($1));
  192. ],
  193. [used], [
  194. int foo( void ) __attribute__(($1));
  195. ],
  196. [visibility], [
  197. int foo_def( void ) __attribute__(($1("default")));
  198. int foo_hid( void ) __attribute__(($1("hidden")));
  199. int foo_int( void ) __attribute__(($1("internal")));
  200. int foo_pro( void ) __attribute__(($1("protected")));
  201. ],
  202. [warning], [
  203. int foo( void ) __attribute__(($1("")));
  204. ],
  205. [warn_unused_result], [
  206. int foo( void ) __attribute__(($1));
  207. ],
  208. [weak], [
  209. int foo( void ) __attribute__(($1));
  210. ],
  211. [weakref], [
  212. static int foo( void ) { return 0; }
  213. static int bar( void ) __attribute__(($1("foo")));
  214. ],
  215. [
  216. m4_warn([syntax], [Unsupported attribute $1, the test may fail])
  217. int foo( void ) __attribute__(($1));
  218. ]
  219. )], [])
  220. ],
  221. dnl GCC doesn't exit with an error if an unknown attribute is
  222. dnl provided but only outputs a warning, so accept the attribute
  223. dnl only if no warning were issued.
  224. [AS_IF([test -s conftest.err],
  225. [AS_VAR_SET([ac_var], [no])],
  226. [AS_VAR_SET([ac_var], [yes])])],
  227. [AS_VAR_SET([ac_var], [no])])
  228. ])
  229. AS_IF([test yes = AS_VAR_GET([ac_var])],
  230. [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_FUNC_ATTRIBUTE_$1), 1,
  231. [Define to 1 if the system has the `$1' function attribute])], [])
  232. AS_VAR_POPDEF([ac_var])
  233. ])