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