(root)/
gcc-13.2.0/
gcc/
testsuite/
c-c++-common/
builtin-has-attribute-3.c
       1  /* Verify __builtin_has_attribute return value for functions.
       2     { dg-do compile }
       3     { dg-options "-Wall -ftrack-macro-expansion=0" }
       4     { dg-options "-Wall -Wno-narrowing -Wno-unused-local-typedefs -ftrack-macro-expansion=0" { target c++ } } 
       5     { dg-additional-options "-DSKIP_ALIAS" { target { { *-*-darwin* hppa*-*-hpux } || { ! alias } } } }
       6  */
       7  
       8  #define ATTR(...) __attribute__ ((__VA_ARGS__))
       9  
      10  void fnone (void);
      11  
      12  ATTR (aligned) void faligned (void);
      13  ATTR (aligned (1)) void faligned_1 (void);
      14  ATTR (aligned (2)) void faligned_2 (void);
      15  ATTR (aligned (4)) void faligned_4 (void);
      16  ATTR (aligned (8)) void faligned_8 (void);
      17  
      18  ATTR (alloc_size (1)) void* falloc_size_1 (int, int);
      19  ATTR (alloc_size (2)) void* falloc_size_2 (int, int);
      20  ATTR (alloc_size (2, 4)) void* falloc_size_2_4 (int, int, int, int);
      21  
      22  ATTR (alloc_align (1)) void* falloc_align_1 (int, int);
      23  ATTR (alloc_align (2)) void* falloc_align_2 (int, int);
      24  ATTR (alloc_align (1), alloc_size (2)) void* falloc_align_1_size_2 (int, int);
      25  ATTR (alloc_align (2), alloc_size (1)) void* falloc_align_2_size_1 (int, int);
      26  
      27  #if __cplusplus
      28  extern "C"
      29  #endif
      30  ATTR (noreturn) void fnoreturn (void) { __builtin_abort (); }
      31  
      32  #ifndef SKIP_ALIAS
      33  ATTR (alias ("fnoreturn")) void falias (void);
      34  #endif
      35  
      36  #define A(expect, sym, attr)						\
      37    typedef int Assert [1 - 2 * !(__builtin_has_attribute (sym, attr) == expect)]
      38  
      39  void test_aligned (void)
      40  {
      41    A (0, fnone, aligned);
      42    A (0, fnone, aligned (0));            /* { dg-warning "requested alignment .0. is not a positive power of 2" } */
      43    A (0, fnone, aligned (1));
      44    A (0, fnone, aligned (2));
      45    A (0, fnone, aligned (4));
      46    A (0, fnone, aligned (8));
      47    A (0, fnone, aligned (16));
      48  
      49    A (1, faligned, aligned);
      50    A (0, faligned, aligned (0));         /* { dg-warning "requested alignment .0. is not a positive power of 2" } */
      51    A (0, faligned, aligned (1));
      52    A (0, faligned, aligned (2));
      53  
      54    A (1, faligned_1, aligned);
      55    A (0, faligned_1, aligned (0));       /* { dg-warning "requested alignment .0. is not a positive power of 2" } */
      56    A (1, faligned_1, aligned (1));
      57    A (0, faligned_1, aligned (2));
      58    A (0, faligned_1, aligned (4));
      59  
      60    A (1, faligned_2, aligned);
      61    A (0, faligned_2, aligned (0));       /* { dg-warning "requested alignment .0. is not a positive power of 2" } */
      62    A (0, faligned_2, aligned (1));
      63    A (1, faligned_2, aligned (2));
      64    A (0, faligned_2, aligned (4));
      65  }
      66  
      67  
      68  void test_alloc_align (void)
      69  {
      70    A (0, fnone, alloc_align);
      71    A (0, falloc_size_1, alloc_align);
      72    A (1, falloc_align_1, alloc_align);
      73    A (1, falloc_align_2, alloc_align);
      74  
      75    A (0, fnone, alloc_align (1));        /* { dg-warning "\\\[-Wattributes" } */
      76    A (0, falloc_size_1, alloc_align (1));
      77    A (1, falloc_align_1, alloc_align (1));
      78    A (0, falloc_align_2, alloc_align (1));   /* { dg-bogus "\\\[-Wattributes" "pr?????" { xfail *-*-* } }" */
      79    A (1, falloc_align_2, alloc_align (2));
      80  }
      81  
      82  
      83  void test_alloc_size_malloc (void)
      84  {
      85    A (0, fnone, alloc_size);
      86    A (0, fnone, alloc_size (1));         /* { dg-warning "\\\[-Wattributes" } */
      87    A (0, fnone, alloc_size (2));         /* { dg-warning "\\\[-Wattributes" } */
      88    A (0, falloc_align_1, alloc_size (1));
      89    A (0, falloc_align_2, alloc_size (1));
      90    A (1, falloc_size_1, alloc_size (1));
      91    A (0, falloc_size_1, alloc_size (2));     /* { dg-bogus "\\\[-Wattributes" "pr?????" { xfail *-*-* } }" */
      92    A (0, falloc_size_2, alloc_size (1));     /* { dg-bogus "\\\[-Wattributes" "pr?????" { xfail *-*-* } }" */
      93    A (1, falloc_size_2, alloc_size (2));
      94  
      95    A (1, falloc_size_2_4, alloc_size);
      96    /* It would probably make more sense to have the built-in return
      97       true only when both alloc_size arguments match, not just one
      98       or the other.  */
      99    A (0, falloc_size_2_4, alloc_size (1));   /* { dg-bogus "\\\[-Wattributes" "pr?????" { xfail *-*-* } }" */
     100    A (1, falloc_size_2_4, alloc_size (2));   /* { dg-bogus "\\\[-Wattributes" "pr?????" { xfail *-*-* } }" */
     101    A (0, falloc_size_2_4, alloc_size (3));   /* { dg-bogus "\\\[-Wattributes" "pr?????" { xfail *-*-* } }" */
     102    A (1, falloc_size_2_4, alloc_size (4));   /* { dg-bogus "\\\[-Wattributes" "pr?????" { xfail *-*-* } }" */
     103    A (1, falloc_size_2_4, alloc_size (2, 4));
     104  
     105    extern ATTR (alloc_size (3))
     106      void* fmalloc_size_3 (int, int, int);
     107  
     108    A (1, fmalloc_size_3, alloc_size);
     109    A (0, fmalloc_size_3, alloc_size (1));    /* { dg-bogus "\\\[-Wattributes" "pr?????" { xfail *-*-* } }" */
     110    A (0, fmalloc_size_3, alloc_size (2));    /* { dg-bogus "\\\[-Wattributes" "pr?????" { xfail *-*-* } }" */
     111    A (1, fmalloc_size_3, alloc_size (3));
     112    A (0, fmalloc_size_3, malloc);
     113  
     114    extern ATTR (malloc)
     115      void* fmalloc_size_3 (int, int, int);
     116  
     117    A (1, fmalloc_size_3, alloc_size (3));
     118    A (1, fmalloc_size_3, malloc);
     119  }
     120  
     121  #ifndef SKIP_ALIAS
     122  void test_alias (void)
     123  {
     124    A (0, fnoreturn, alias);
     125    A (1, falias, alias);
     126    A (1, falias, alias ("fnoreturn"));
     127    A (0, falias, alias ("falias"));
     128    A (0, falias, alias ("fnone"));
     129  }
     130  #endif
     131  
     132  void test_cold_hot (void)
     133  {
     134    extern ATTR (cold) void fcold (void);
     135    extern ATTR (hot) void fhot (void);
     136  
     137    A (0, fnone, cold);
     138    A (0, fnone, hot);
     139  
     140    A (1, fcold, cold);
     141    A (0, fcold, hot);
     142  
     143    A (0, fhot, cold);
     144    A (1, fhot, hot);
     145  }
     146  
     147  
     148  void test_const_leaf_pure (void)
     149  {
     150    extern ATTR (const) int fconst (void);
     151    extern ATTR (leaf) int fleaf (void);
     152    extern ATTR (pure) int fpure (void);
     153  
     154    A (0, fnone, const);
     155    A (0, fnone, leaf);
     156    A (0, fnone, pure);
     157  
     158    A (1, fconst, const);
     159    A (0, fconst, leaf);
     160    A (0, fconst, pure);
     161  
     162    A (0, fleaf, const);
     163    A (1, fleaf, leaf);
     164    A (0, fleaf, pure);
     165  
     166    A (0, fpure, const);
     167    A (0, fpure, leaf);
     168    A (1, fpure, pure);
     169  
     170    extern ATTR (const, leaf) int fconst_leaf (void);
     171  
     172    A (1, fconst_leaf, const);
     173    A (1, fconst_leaf, leaf);
     174  
     175    extern ATTR (leaf, const) int fleaf_const (void);
     176  
     177    A (1, fleaf_const, const);
     178    A (1, fleaf_const, leaf);
     179  }
     180  
     181  
     182  void test_ctor_dtor (void)
     183  {
     184    extern ATTR (constructor) void fctor (void);
     185    extern ATTR (destructor) void fdtor (void);
     186    extern ATTR (constructor, destructor) void fctor_dtor (void);
     187  
     188    A (0, fnone, constructor);
     189    A (0, fnone, destructor);
     190  
     191    A (1, fctor, constructor);
     192    A (1, fdtor, destructor);
     193  
     194    extern ATTR (constructor) void fctor_dtor (void);
     195    extern ATTR (destructor) void fctor_dtor (void);
     196    extern ATTR (constructor, destructor) void fctor_dtor (void);
     197  
     198    A (1, fctor_dtor, constructor);
     199    A (1, fctor_dtor, destructor);
     200  }
     201  
     202  
     203  void test_externally_visible (void)
     204  {
     205    extern void fexternally_visible (void);
     206  
     207    A (0, fexternally_visible, externally_visible);
     208  
     209    extern ATTR (externally_visible) void fexternally_visible (void);
     210  
     211    A (1, fexternally_visible, externally_visible);
     212  }
     213  
     214  
     215  void test_flatten (void)
     216  {
     217    extern void fflatten (void);
     218  
     219    A (0, fflatten, flatten);
     220  
     221    extern ATTR (flatten) void fflatten (void);
     222  
     223    A (1, fflatten, flatten);
     224  
     225    extern void fflatten (void);
     226  
     227    A (1, fflatten, flatten);
     228  }
     229  
     230  
     231  ATTR (format (printf, 2, 4)) void
     232  fformat_printf_2_3 (int, const char*, int, ...);
     233  
     234  void test_format (void)
     235  {
     236    A (0, fnone, format);
     237    A (0, fnone, format (printf));
     238    A (0, fnone, format (printf, 2));
     239  }
     240  
     241  
     242  inline void finline (void) { }
     243  inline ATTR (always_inline) void falways_inline (void) { }
     244  inline ATTR (always_inline, gnu_inline) void falways_gnu_inline (void) { }
     245  ATTR (noinline) void fnoinline () { }
     246  
     247  void test_inline (void)
     248  {
     249    A (0, fnone, always_inline);
     250    A (0, fnone, gnu_inline);
     251    A (0, fnone, noinline);
     252  
     253    A (0, finline, always_inline);
     254    A (0, finline, gnu_inline);
     255    A (0, finline, noinline);
     256  
     257    A (1, falways_inline, always_inline);
     258    A (0, falways_inline, gnu_inline);
     259    A (0, falways_inline, noinline);
     260  
     261    A (1, falways_gnu_inline, always_inline);
     262    A (1, falways_gnu_inline, gnu_inline);
     263    A (0, falways_gnu_inline, noinline);
     264  
     265    A (0, fnoinline, always_inline);
     266    A (0, fnoinline, gnu_inline);
     267    A (1, fnoinline, noinline);
     268  }
     269  
     270  
     271  ATTR (no_instrument_function) void fno_instrument (void);
     272  
     273  ATTR (visibility ("default")) void fdefault (void);
     274  ATTR (visibility ("hidden")) void fhidden (void);
     275  ATTR (visibility ("internal")) void finternal (void);
     276  ATTR (visibility ("protected")) void fprotected (void);
     277  
     278  void test_visibility (void)
     279  {
     280    A (0, fnone, visibility ("default"));
     281    A (0, fnone, visibility ("hidden"));
     282    A (0, fnone, visibility ("internal"));
     283    A (0, fnone, visibility ("protected"));
     284  
     285    A (1, fdefault, visibility ("default"));
     286    A (0, fdefault, visibility ("hidden"));
     287    A (0, fdefault, visibility ("internal"));
     288    A (0, fdefault, visibility ("protected"));
     289  
     290    A (0, fhidden, visibility ("default"));
     291    A (1, fhidden, visibility ("hidden"));
     292    A (0, fhidden, visibility ("internal"));
     293    A (0, fhidden, visibility ("protected"));
     294  
     295    A (0, finternal, visibility ("default"));
     296    A (0, finternal, visibility ("hidden"));
     297    A (1, finternal, visibility ("internal"));
     298    A (0, finternal, visibility ("protected"));
     299  
     300    A (0, fprotected, visibility ("default"));
     301    A (0, fprotected, visibility ("hidden"));
     302    A (0, fprotected, visibility ("internal"));
     303    A (1, fprotected, visibility ("protected"));
     304  }
     305  
     306  /* { dg-prune-output "specifies less restrictive attribute" } */