(root)/
gcc-13.2.0/
gcc/
testsuite/
c-c++-common/
builtin-has-attribute-2.c
       1  /* Verify __builtin_has_attribute return value for types.
       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  
       6  #define ATTR(...) __attribute__ ((__VA_ARGS__))
       7  
       8  #define A(expect, sym, attr)						\
       9    typedef int Assert [1 - 2 * !(__builtin_has_attribute (sym, attr) == expect)]
      10  
      11  struct ATTR (packed) Packed { char c; int i; };
      12  
      13  void fvoid (void);
      14  struct Packed fpacked (void);
      15  
      16  union OrdinaryUnion { void *p; int i; };
      17  union ATTR (transparent_union) TransparentUnion { void *p; int i; };
      18  
      19  /* Exercise __builtin_has_attribute with the first argument that
      20     is a type.  */
      21  
      22  void test_type (int n)
      23  {
      24    /* Verify both forms of the attribute spelling.  Unlike the attribute
      25       keyword that can be spelled three ways (with either leading or
      26       trailing underscores, or with both), attribute names can only be
      27       spelled two ways.  */
      28    A (0, int, aligned);
      29    A (0, int, __aligned__);
      30  
      31    A (0, int, aligned (1));
      32    A (0, int, aligned (2));
      33    A (0, int[1], aligned);
      34    A (0, int[1], aligned (2));
      35    A (0, int[n], aligned);
      36    A (0, int[n], aligned (4));
      37  
      38    /* Again, verify both forms of the attribute spelling.  */
      39    A (1, ATTR (aligned) char, aligned);
      40    A (1, ATTR (aligned (2)) short, aligned);
      41    A (1, ATTR (aligned (4)) int, __aligned__);
      42  
      43    A (0, int ATTR (aligned (4)), aligned (2));
      44    A (0, int ATTR (aligned (2)), aligned (4));
      45    /* GCC retains both attributes when the type is defined in the builtin.  */
      46    A (1, int ATTR (aligned (2), aligned (4)), aligned (2));
      47    A (1, int ATTR (aligned (2), aligned (4)), aligned (4));
      48    /* The following fails due to bug 87524.
      49       A (1, int ATTR (aligned (4), aligned (2))), aligned (4)); */
      50    A (0, int ATTR (aligned (4), aligned (2)), aligned (8));
      51  
      52    A (1, int ATTR (aligned (8)), aligned (1 + 7));
      53  
      54    enum { eight = 8 };
      55    A (1, int ATTR (aligned (8)), aligned (eight));
      56    A (1, int ATTR (aligned (eight)), aligned (1 + 7));
      57  
      58    struct NotPacked { char c; int i; };
      59    A (0, struct NotPacked, packed);
      60    A (1, struct Packed, packed);
      61  
      62    /* Exercise types returned from a function.  */
      63    A (0, fvoid (), packed);
      64    A (1, fpacked (), packed);
      65  
      66    struct ATTR (aligned (2), packed) Aligned2Packed { char c; int i; };
      67    A (1, struct Aligned2Packed, aligned);
      68    A (1, struct Aligned2Packed, aligned (2));
      69    A (0, struct Aligned2Packed, aligned (4));
      70    A (1, struct Aligned2Packed, packed);
      71  
      72    A (0, int, may_alias);
      73    A (1, ATTR (may_alias) int, may_alias);
      74  
      75    A (0, char, warn_if_not_aligned (1));
      76    A (0, char, warn_if_not_aligned (2));
      77  
      78    A (1, ATTR (warn_if_not_aligned (2)) char, warn_if_not_aligned);
      79    A (0, ATTR (warn_if_not_aligned (2)) char, warn_if_not_aligned (1));
      80    A (1, ATTR (warn_if_not_aligned (2)) char, warn_if_not_aligned (2));
      81    A (0, ATTR (warn_if_not_aligned (2)) char, warn_if_not_aligned (4));
      82  
      83    A (0, union OrdinaryUnion, transparent_union);
      84  
      85    A (1, union TransparentUnion, transparent_union);
      86    A (1, const union TransparentUnion, transparent_union);
      87  }
      88  
      89  /* Exercise __builtin_has_attribute with the first argument that
      90     is a typedef.  */
      91  
      92  void test_typedef (int n)
      93  {
      94    typedef char A1[1];
      95    A (0, A1, aligned);
      96    A (0, A1, aligned (1));
      97    A (0, A1, aligned (2));
      98  
      99    typedef char An[n];
     100    A (0, An, aligned);
     101    A (0, An, aligned (1));
     102    A (0, An, aligned (2));
     103  
     104    typedef ATTR (aligned (8)) short AI8;
     105    A (1, AI8, aligned);
     106    A (0, AI8, aligned (4));
     107    A (1, AI8, aligned (8));
     108    A (0, AI8, aligned (16));
     109  
     110    A (1, const AI8, aligned);
     111    A (1, const volatile AI8, aligned);
     112  
     113    typedef ATTR (aligned (2), aligned (8), aligned (16)) int AI16;
     114    A (1, AI16, aligned);
     115    A (0, AI16, aligned (1));
     116    A (0, AI16, aligned (2));
     117    A (0, AI16, aligned (4));
     118    A (0, AI16, aligned (8));
     119    A (1, AI16, aligned (16));
     120    A (0, AI16, aligned (32));
     121  
     122    typedef const AI16 CAI16;
     123    A (1, CAI16, aligned);
     124    A (0, CAI16, aligned (1));
     125    A (1, CAI16, aligned (16));
     126  
     127    typedef int I;
     128    A (0, I, may_alias);
     129    A (0, AI8, may_alias);
     130  
     131    typedef ATTR (may_alias) int MAI;
     132    A (1, MAI, may_alias);
     133  
     134    typedef ATTR (aligned (4), may_alias) char A4MAC;
     135    A (0, A4MAC, aligned (0));    /* { dg-warning "requested alignment .0. is not a positive power of 2" } */
     136    A (0, A4MAC, aligned (1));
     137    A (0, A4MAC, aligned (2));
     138    A (1, A4MAC, aligned (4));
     139    A (0, A4MAC, aligned (8));
     140    A (1, A4MAC, may_alias);
     141  
     142    typedef ATTR (may_alias, aligned (8)) char A8MAC;
     143    A (1, A8MAC, aligned);
     144    A (0, A8MAC, aligned (0));    /* { dg-warning "requested alignment .0. is not a positive power of 2" } */
     145    A (0, A8MAC, aligned (1));
     146    A (0, A8MAC, aligned (2));
     147    A (0, A8MAC, aligned (4));
     148    A (1, A8MAC, aligned (8));
     149    A (0, A8MAC, aligned (16));
     150    A (1, A8MAC, may_alias);
     151  
     152    typedef ATTR (may_alias) const AI8 CMAI8;
     153    A (1, CMAI8, aligned);
     154    A (1, CMAI8, may_alias);
     155    A (0, CMAI8, aligned (4));
     156    A (1, CMAI8, aligned (8));
     157  
     158    typedef void Fnull (void*, void*, void*);
     159    A (0, Fnull, nonnull);
     160    A (0, Fnull, nonnull (1));
     161    A (0, Fnull, nonnull (2));
     162    A (0, Fnull, nonnull (3));
     163  
     164    typedef ATTR (nonnull) Fnull Fnonnull;
     165    A (1, Fnonnull, nonnull);
     166    A (1, Fnonnull, nonnull (1));
     167    A (1, Fnonnull, nonnull (2));
     168    A (1, Fnonnull, nonnull (3));
     169  
     170    typedef ATTR (nonnull (2)) void Fnonnull_2 (void*, void*, void*);
     171    A (0, Fnonnull_2, nonnull);
     172    A (0, Fnonnull_2, nonnull (1));
     173    A (1, Fnonnull_2, nonnull (2));
     174    A (0, Fnonnull_2, nonnull (3));
     175  
     176    typedef ATTR (nonnull (1), nonnull (2), nonnull (3))
     177      void Fnonnull_1_2_3 (void*, void*, void*);
     178  
     179    /* The following fails because  the built-in doesn't recognize that
     180       a single nonnull with no arguments is the same as one nonnull for
     181       each function parameter.  Disable the testing for now.
     182       A (1, Fnonnull_1_2_3, nonnull);
     183    */
     184    A (1, Fnonnull_1_2_3, nonnull (1));
     185    A (1, Fnonnull_1_2_3, nonnull (2));
     186    A (1, Fnonnull_1_2_3, nonnull (3));
     187  
     188    typedef void Freturns (void);
     189    A (0, Fnull, noreturn);
     190    A (0, Freturns, noreturn);
     191  
     192    typedef ATTR (warn_if_not_aligned (8)) char CWA8;
     193    A (0, CWA8, warn_if_not_aligned (2));
     194    A (0, CWA8, warn_if_not_aligned (4));
     195    A (1, CWA8, warn_if_not_aligned (8));
     196    A (0, CWA8, warn_if_not_aligned (16));
     197  
     198    typedef union OrdinaryUnion OrdUnion;
     199    A (0, OrdUnion, transparent_union);
     200  
     201    /* The attribute is ignored on typedefs but GCC fails to diagnose
     202       it (see bug ).  */
     203    typedef union ATTR (transparent_union)
     204      OrdinaryUnion TransUnion;   /* { dg-warning "\\\[-Wattributes" "pr87578" { xfail { ! { c++ } } } } */
     205    A (0, TransUnion, transparent_union);
     206  }