1  /* Verify that __builtin_has_attribute detects attributes aligned
       2     and packed in various forms of array dereferencing and indirection
       3     expressions correspondingly to __alignof__.
       4     { dg-do compile }
       5     { dg-options "-Wall -Wno-unused -ftrack-macro-expansion=0" }
       6     { dg-require-effective-target size24plus } */
       7  
       8  #define ATTR(...) __attribute__ ((__VA_ARGS__))
       9  #define ALIGN(N)  ATTR (aligned (N))
      10  
      11  #define Assert(expr) typedef int _Assert [1 - 2 * !(expr)]
      12  
      13  /* Verify that  __builtin_has_attribute (EXPR, align (ALIGN)) returns
      14     the EXPECTed result.  When EXPECT is true, verify that the EXPression
      15     has the expected ALIGNment.    */
      16  #define A3(expect, expr, align) do {					\
      17      Assert (!expect || __alignof__ (expr) == align);			\
      18      Assert (expect == __builtin_has_attribute (expr, aligned (align))); \
      19    } while (0)
      20  
      21  #define A(expect, expr)							\
      22    Assert (expect == __builtin_has_attribute (expr, aligned))		\
      23  
      24  enum { PA = __alignof__ (void*) };
      25  
      26  /* Define pointer to pointer types, with different alignments
      27     at each level of indirection.  */
      28  typedef struct S8 { char a[8]; }   S8;
      29  typedef ALIGN (8)  S8              I8;
      30  typedef ALIGN (16) I8             *P16_I8;
      31  typedef            P16_I8         *P_P16_I8;
      32  typedef ALIGN (32) P_P16_I8       *P32_P_P16_I8;
      33  typedef            P32_P_P16_I8   *P_P32_P_P16_I8;
      34  typedef ALIGN (64) P_P32_P_P16_I8 *P64_P_P32_P_P16_I8;
      35  
      36  Assert ( 8 == __alignof__ (I8));
      37  Assert (16 == __alignof__ (P16_I8));
      38  Assert (PA == __alignof__ (P_P16_I8));
      39  Assert (32 == __alignof__ (P32_P_P16_I8));
      40  Assert (PA == __alignof__ (P_P32_P_P16_I8));
      41  Assert (64 == __alignof__ (P64_P_P32_P_P16_I8));
      42  
      43  
      44  /* Similar to the pointer of pointers above, define array of array
      45     types, with different alignments at each level of indirection.  */
      46  typedef struct S64 { char a[64]; } S64;
      47  typedef ALIGN (64) S64             I64;
      48  typedef ALIGN (32) I64             A32_I64[3];
      49  typedef            A32_I64         A_A32_I64[5];
      50  typedef ALIGN (16) A_A32_I64       A16_A_A32_I64[7];
      51  typedef            A16_A_A32_I64   A_A16_A_A32_I64[11];
      52  typedef ALIGN (8)  A_A16_A_A32_I64 A8_A_A16_A_A32_I64[13];
      53  
      54  Assert (64 == __alignof__ (I64));
      55  Assert (32 == __alignof__ (A32_I64));
      56  /* With no explicit alignment, an array of overaligned elements
      57     is considered to have the alignment of its elements.  */
      58  Assert (32 == __alignof__ (A_A32_I64));
      59  Assert (16 == __alignof__ (A16_A_A32_I64));
      60  Assert (16 == __alignof__ (A_A16_A_A32_I64));
      61  Assert ( 8 == __alignof__ (A8_A_A16_A_A32_I64));
      62  
      63  
      64  void test_arrays (void)
      65  {
      66    /* Verify that the aligned attribute on each of the composite types
      67       is detected corresponding to the result of __alignof__.  */
      68    A (1, (*(A8_A_A16_A_A32_I64*)0));
      69    A3 (1, (*(A8_A_A16_A_A32_I64*)0), 8);
      70    A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0], 8);
      71    /* GCC propagates the user-align bit from element types to their
      72       arrays but it doesn't propagate the attribute itself.  The built-in
      73       considers both the  bit and the attribute so it succeeds below even
      74       though the referenced type isn't declared with the attribute.  */
      75    A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0], 8);
      76    A3 (1, (*(A8_A_A16_A_A32_I64*)0)[0], 16);
      77    A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0], 32);
      78    A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1], 8);
      79    A3 (1, (*(A8_A_A16_A_A32_I64*)0)[0][1], 16);
      80    A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1], 32);
      81    A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1][2], 16);
      82    A3 (1, (*(A8_A_A16_A_A32_I64*)0)[0][1][2], 32);
      83    A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1][2], 64);
      84    A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1][2][3], 16);
      85    A3 (1, (*(A8_A_A16_A_A32_I64*)0)[0][1][2][3], 32);
      86    A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1][2][3], 64);
      87    A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1][2][3][4], 32);
      88    A3 (1, (*(A8_A_A16_A_A32_I64*)0)[0][1][2][3][4], 64);
      89    A3 (0, (*(A8_A_A16_A_A32_I64*)0)[0][1][2][3][4], 128);
      90  
      91    A8_A_A16_A_A32_I64 a;
      92    A3 (0, a[0], 8);
      93    A3 (1, a[0], 16);
      94    A3 (0, a[0], 32);
      95    A3 (0, a[0][1], 8);
      96    A3 (1, a[0][1], 16);
      97    A3 (0, a[0][1], 32);
      98    A3 (0, a[0][1][2], 16);
      99    A3 (1, a[0][1][2], 32);
     100    A3 (0, a[0][1][2], 64);
     101    A3 (0, a[0][1][2][3], 16);
     102    A3 (1, a[0][1][2][3], 32);
     103    A3 (0, a[0][1][2][3], 64);
     104    A3 (0, a[0][1][2][3][4], 32);
     105    A3 (1, a[0][1][2][3][4], 64);
     106    A3 (0, a[0][1][2][3][4], 128);
     107  }
     108  
     109  void test_pointers (void)
     110  {
     111    /* Verify that the aligned attribute on each of the composite pointer
     112       types is detected corresponding to the result of __alignof__.  */
     113    A (1, I8);
     114    A3 (0, I8, 4);
     115    A3 (1, I8, 8);
     116  
     117    A (1, P16_I8);
     118    A3 (0, P16_I8, 8);
     119    A3 (1, P16_I8, 16);
     120  
     121    A (0, P_P16_I8);
     122    A3 (0, P_P16_I8, 8);
     123    A3 (0, P_P16_I8, 16);
     124  
     125    A (1, P32_P_P16_I8);
     126    A3 (0, P32_P_P16_I8, 8);
     127    A3 (0, P32_P_P16_I8, 16);
     128    A3 (1, P32_P_P16_I8, 32);
     129  
     130    A (0, P_P32_P_P16_I8);
     131  
     132    A (1, P64_P_P32_P_P16_I8);
     133    A3 (0, P64_P_P32_P_P16_I8, 8);
     134    A3 (0, P64_P_P32_P_P16_I8, 16);
     135    A3 (0, P64_P_P32_P_P16_I8, 32);
     136    A3 (1, P64_P_P32_P_P16_I8, 64);
     137  
     138  
     139    /* Verify that the attribute on each of the composite types is detected
     140       in the type of each of the indirection expressions.  */
     141    A (1, *(P16_I8)0);
     142    A3 (1, *(P16_I8)0, 8);
     143    A3 (0, *(P16_I8)0, 16);
     144  
     145    A (1, *(P_P16_I8)0);
     146    A3 (0, *(P_P16_I8)0, 8);
     147    A3 (1, *(P_P16_I8)0, 16);
     148  
     149    A (0, *(P32_P_P16_I8)0);
     150    A3 (0, *(P32_P_P16_I8)0, 8);
     151    A3 (0, *(P32_P_P16_I8)0, 16);
     152    A3 (0, *(P32_P_P16_I8)0, 32);
     153  
     154    A (1, *(P_P32_P_P16_I8)0);
     155    A3 (1, *(P_P32_P_P16_I8)0, 32);
     156  
     157    A (0, *(P64_P_P32_P_P16_I8)0);
     158  
     159    /* Verify that the attribute on each of the composite types is detected
     160       in the type of each of the subscipting expressions.  */
     161    A (1, ((P16_I8)0)[0]);
     162    A3 (1, ((P16_I8)0)[1], 8);
     163    A3 (0, ((P16_I8)0)[2], 16);
     164  
     165    A (1, ((P_P16_I8)0)[3]);
     166    A3 (0, ((P_P16_I8)0)[4], 8);
     167    A3 (1, ((P_P16_I8)0)[5], 16);
     168  
     169    A (0, ((P32_P_P16_I8)0)[6]);
     170    A3 (0, ((P32_P_P16_I8)0)[7], 8);
     171    A3 (0, ((P32_P_P16_I8)0)[8], 16);
     172    A3 (0, ((P32_P_P16_I8)0)[9], 32);
     173  
     174    A (1, ((P_P32_P_P16_I8)0)[10]);
     175    A3 (1, ((P_P32_P_P16_I8)0)[11], 32);
     176  
     177    A (0, ((P64_P_P32_P_P16_I8)0)[12]);
     178  
     179  
     180    /* Verify that the attribute on each of the composite types is detected
     181       in the type of each of the subscipting expression involving variables.  */
     182  
     183    I8                   i8;
     184    P16_I8               p16_i8 = &i8;
     185    P_P16_I8             p_p16_i8 = &p16_i8;
     186    P32_P_P16_I8         p32_p_p16_i8 = &p_p16_i8;
     187    P_P32_P_P16_I8       p_p32_p_p16_i8 = &p32_p_p16_i8;
     188    P64_P_P32_P_P16_I8   p64_p_p32_p_p16_i8 = &p_p32_p_p16_i8;
     189  
     190    A (1, p16_i8[0]);
     191    A3 (1, p16_i8[1], 8);
     192    A3 (0, p16_i8[2], 16);
     193  
     194    A (1, p_p16_i8[3]);
     195    A3 (0, p_p16_i8[4], 8);
     196    A3 (1, p_p16_i8[5], 16);
     197  
     198    A (0, p32_p_p16_i8[6]);
     199    A3 (0, p32_p_p16_i8[7], 8);
     200    A3 (0, p32_p_p16_i8[8], 16);
     201    A3 (0, p32_p_p16_i8[9], 32);
     202  
     203    A (1, p_p32_p_p16_i8[10]);
     204    A3 (1, p_p32_p_p16_i8[11], 32);
     205  
     206  
     207    A (1, p_p16_i8[0][1]);
     208    A3 (1, p_p16_i8[1][2], 8);
     209    A3 (0, p_p16_i8[2][3], 16);
     210  
     211  
     212    A (0, p64_p_p32_p_p16_i8[0]);
     213  
     214    A (1, p64_p_p32_p_p16_i8[0][1]);
     215    A3 (0, p64_p_p32_p_p16_i8[0][2], 16);
     216    A3 (1, p64_p_p32_p_p16_i8[0][3], 32);
     217    A3 (0, p64_p_p32_p_p16_i8[0][4], 64);
     218  
     219    A (0, p64_p_p32_p_p16_i8[0][1][2]);
     220  
     221    A (1, p64_p_p32_p_p16_i8[0][1][2][3]);
     222    A3 (0, p64_p_p32_p_p16_i8[0][1][2][4], 8);
     223    A3 (1, p64_p_p32_p_p16_i8[0][1][2][4], 16);
     224    A3 (0, p64_p_p32_p_p16_i8[0][1][2][4], 32);
     225  
     226    A (1, p64_p_p32_p_p16_i8[0][1][2][3][4]);
     227    A3 (1, p64_p_p32_p_p16_i8[0][1][2][3][5], 8);
     228    A3 (0, p64_p_p32_p_p16_i8[0][1][2][4][6], 16);
     229  
     230  
     231    /* Same as above but using the indirection expression.  */
     232    A (0, *p64_p_p32_p_p16_i8);
     233  
     234    A (1, **p64_p_p32_p_p16_i8);
     235    A3 (0, **p64_p_p32_p_p16_i8, 16);
     236    A3 (1, **p64_p_p32_p_p16_i8, 32);
     237    A3 (0, **p64_p_p32_p_p16_i8, 64);
     238  
     239    A (0, ***p64_p_p32_p_p16_i8);
     240  
     241    A (1, ****p64_p_p32_p_p16_i8);
     242    A3 (0, ****p64_p_p32_p_p16_i8, 8);
     243    A3 (1, ****p64_p_p32_p_p16_i8, 16);
     244    A3 (0, ****p64_p_p32_p_p16_i8, 32);
     245  
     246    A (1, *****p64_p_p32_p_p16_i8);
     247    A3 (1, *****p64_p_p32_p_p16_i8, 8);
     248    A3 (0, *****p64_p_p32_p_p16_i8, 16);
     249  }
     250  
     251  
     252  S8 f_S8 (void);
     253  I8 f_I8 (void);
     254  P16_I8 f_P16_I8 (void);
     255  P_P16_I8 f_P_P16_I8 (void);
     256  P32_P_P16_I8 f_P32_P_P16_I8 (void);
     257  P_P32_P_P16_I8 f_P_P32_P_P16_I8 (void);
     258  P64_P_P32_P_P16_I8 f_P64_P_P32_P_P16_I8 (void);
     259  
     260  void test_function_call (void)
     261  {
     262    /* Verify that the aligned attribute on each of the composite pointer
     263       types returned by the functions is detected corresponding to
     264       the result of __alignof__.  */
     265  
     266    A (0, f_S8 ());
     267  
     268    A (1, f_I8 ());
     269    A3 (1, f_I8 (), 8);
     270    A3 (0, f_I8 (), 16);
     271  
     272    A (1, f_P16_I8 ());
     273    A3 (0, f_P16_I8 (), 8);
     274    A3 (1, f_P16_I8 (), 16);
     275    A3 (0, f_P16_I8 (), 32);
     276  
     277    A (1, *f_P16_I8 ());
     278    A3 (1, *f_P16_I8 (), 8);
     279    A3 (0, *f_P16_I8 (), 16);
     280  
     281    A (0, f_P_P16_I8 ());
     282  
     283    A (1, *f_P_P16_I8 ());
     284    A3 (0, *f_P_P16_I8 (), 8);
     285    A3 (1, *f_P_P16_I8 (), 16);
     286    A3 (0, *f_P_P16_I8 (), 32);
     287  
     288    A (1, **f_P_P16_I8 ());
     289    A3 (1, **f_P_P16_I8 (), 8);
     290    A3 (0, **f_P_P16_I8 (), 16);
     291    A3 (0, **f_P_P16_I8 (), 32);
     292  }
     293  
     294  
     295  void test_compound_literal (void)
     296  {
     297    A (0, (S8){ });
     298  
     299    A (1, (I8){ });
     300    A3 (1, (I8){ }, 8);
     301    A3 (0, (I8){ }, 16);
     302  
     303    A (1, (I64){ });
     304    A3 (0, (I64){ }, 8);
     305    A3 (0, (I64){ }, 16);
     306    A3 (0, (I64){ }, 32);
     307    A3 (1, (I64){ }, 64);
     308  
     309    A (1, (A32_I64){ 0 });
     310    A3 (0, (A32_I64){ 0 }, 8);
     311    A3 (0, (A32_I64){ 0 }, 16);
     312    A3 (1, (A32_I64){ 0 }, 32);
     313    A3 (0, (A32_I64){ 0 }, 64);
     314  
     315    A (1, ((A32_I64){ 0 })[0]);
     316    A3 (0, ((A32_I64){ 0 })[0], 8);
     317    A3 (0, ((A32_I64){ 0 })[0], 16);
     318    A3 (0, ((A32_I64){ 0 })[0], 32);
     319    A3 (1, ((A32_I64){ 0 })[0], 64);
     320  }
     321  
     322  
     323  void test_ternary_expression (int i)
     324  {
     325    A (0, (0 ? (S8){ } : (S8){ }));
     326  
     327    A (1, (1 ? (I8){ } : (I8){ }));
     328    A3 (1, (2 ? (I8){ } : (I8){ }), 8);
     329    A3 (0, (3 ? (I8){ } : (I8){ }), 16);
     330  
     331    A (1, (4 ? (I64){ } : (I64){ }));
     332    A3 (0, (5 ? (I64){ } : (I64){ }), 8);
     333    A3 (0, (6 ? (I64){ } : (I64){ }), 16);
     334    A3 (0, (7 ? (I64){ } : (I64){ }), 32);
     335    A3 (1, (8 ? (I64){ } : (I64){ }), 64);
     336  
     337  #if !__cplusplus
     338    /* Suppress -Wc++-compat warning: converting an array compound literal
     339       to a pointer is ill-formed in C++  */
     340  # pragma GCC diagnostic ignored "-Wc++-compat"
     341  
     342    A (0, (9 ? (A32_I64){ } : (A32_I64){ })); 
     343    A3 (0, (i ? (A32_I64){ } : (A32_I64){ }), 8);
     344    A3 (0, (i++ ? (A32_I64){ } : (A32_I64){ }), 16);
     345    A3 (0, (++i ? (A32_I64){ } : (A32_I64){ }), 32);
     346    A3 (0, (!i ? (A32_I64){ } : (A32_I64){ }), 64);
     347  
     348    A (1, (0 ? (A32_I64){ } : (A32_I64){ })[0]);
     349    A3 (0, (1 ? (A32_I64){ } : (A32_I64){ })[1], 8);
     350    A3 (0, (2 ? (A32_I64){ } : (A32_I64){ })[2], 16);
     351    A3 (0, (3 ? (A32_I64){ } : (A32_I64){ })[3], 32);
     352    A3 (1, (3 ? (A32_I64){ } : (A32_I64){ })[i], 64);
     353  #endif
     354  }
     355  
     356  
     357  void test_comma_expression (int i)
     358  {
     359  #if __cplusplus
     360    /* In C++, the type of the comma expressions whose operand is an array
     361       is the array itself with any attributes it was defined with.  */
     362  # define R 1
     363  #else
     364    /* In C, the type of the comma expressions whose operand is an array
     365       is a pointer type that does not include any attributes the array
     366       was defined with.  */
     367  # define R 0
     368  /* Suppress -Wc++-compat warning: converting an array compound literal
     369     to a pointer is ill-formed in C++
     370     G++ accepts the conversion in unevaluated contexts without a warning.  */
     371  # pragma GCC diagnostic ignored "-Wc++-compat"
     372  #endif
     373  
     374    A (0, (0, (S8){ }));
     375  
     376    A (1, (0, (I8){ }));
     377    A3 (1, (1, (I8){ }), 8);
     378    A3 (0, (2, (I8){ }), 16);
     379  
     380    A (1, (3, (I64){ }));
     381    A3 (0, (4, (I64){ }), 8);
     382    A3 (0, (5, (I64){ }), 16);
     383    A3 (0, (6, (I64){ }), 32);
     384    A3 (1, (7, (I64){ }), 64);
     385  
     386    A (R, (8, (A32_I64){ }));
     387    A3 (0, (9, (A32_I64){ }), 8);
     388    A3 (0, ((void)0, (A32_I64){ }), 16);
     389    A3 (R, ((I64){ },(A32_I64){ }), 32);
     390    A3 (0, (0, (A32_I64){ }), 64);
     391  
     392    A (1, (1, ((A32_I64){ })[0]));
     393    A3 (0, (2, ((A32_I64){ })[0]), 8);
     394    A3 (0, (i++, ((A32_I64){ })[0]), 16);
     395    A3 (0, (++i, ((A32_I64){ })[0]), 32);
     396    A3 (1, (i = 0, ((A32_I64){ })[0]), 64);
     397  }