1  /* PR c/88383 - ICE calling _builtin_has_attribute(r, aligned(N)))
       2     on an overaligned reference r
       3     PR c/89288 - ICE in tree_code_size, at tree.c:865
       4     { dg-options "-Wall -ftrack-macro-expansion=0" }
       5     { dg-options "-Wall -Wno-narrowing -Wno-unused -ftrack-macro-expansion=0" { target c++ } }  */
       6  
       7  #define ATTR(...) __attribute__ ((__VA_ARGS__))
       8  
       9  #define A(expect, sym, attr)						\
      10    typedef int Assert [1 - 2 * !(__builtin_has_attribute (sym, attr) == expect)]
      11  
      12  typedef ATTR (aligned (8)) int Int8;
      13  
      14  /* The attribute applies to the array, not to the type of its elements.  */
      15  extern ATTR (aligned (8)) char i8arr[];
      16  
      17  /* The attribute applies to the pointer, not to the type it points to.  */
      18  extern ATTR (aligned (8)) int *ptr;
      19  extern Int8 *i8ptr;
      20  
      21  #if __cplusplus
      22  
      23  /* Similarly here, the attribute applies to the reference, not to its type.  */
      24  extern ATTR (aligned (8)) int &ref;
      25  extern Int8 &i8ref;
      26  
      27  #else
      28  
      29  /* Fake references in C.  */
      30  extern ATTR (aligned (8)) int ref;
      31  Int8 i8ref;
      32  
      33  #endif
      34  
      35  void test (void)
      36  {
      37    /* Verify that the built-in detects the attribute on the array. */
      38    A (1, i8arr, aligned);
      39    A (0, i8arr, aligned (1));
      40    A (0, i8arr, aligned (2));
      41    A (0, i8arr, aligned (4));
      42    A (1, i8arr, aligned (8));
      43    A (0, i8arr, aligned (16));
      44  
      45    A (0, i8arr + 1, aligned);
      46    A (0, i8arr + 2, aligned (1));
      47    A (0, i8arr + 3, aligned (8));
      48  
      49    /* Verify the builtin detects the absence of the attribute on
      50       the elements.  */
      51    A (0, i8arr[0], aligned);
      52    A (0, *i8arr,   aligned);
      53  
      54    /* Verify that the built-in doesn't confuse the attribute on
      55       the pointer type with that to the pointed to type.  This
      56       also exercises PR c/89288.  */
      57    A (0, (Int8*)0, aligned);
      58    A (0, (int*)0,  aligned);
      59    A (0, (void*)0, aligned);
      60    A (0, 0,        aligned);
      61  
      62    /* Verify that the built-in detects the attribute on the pointer
      63       itself. */
      64    A (1, ptr, aligned);
      65    A (0, ptr, aligned (1));
      66    A (0, ptr, aligned (2));
      67    A (0, ptr, aligned (4));
      68    A (1, ptr, aligned (8));
      69    A (0, ptr, aligned (16));
      70  
      71    A (0, ptr + 1, aligned);
      72    A (0, ptr + 2, aligned (1));
      73    A (0, ptr + 3, aligned (8));
      74  
      75    /* The pointed to type is not declared with attribute aligned.  */
      76    A (0, *ptr, aligned);
      77    A (0, *ptr, aligned (1));
      78    A (0, *ptr, aligned (2));
      79    A (0, *ptr, aligned (4));
      80    A (0, *ptr, aligned (8));
      81    A (0, *ptr, aligned (16));
      82  
      83    A (0, *ptr + 1, aligned);
      84    A (0, *ptr + 2, aligned (1));
      85    A (0, *ptr + 3, aligned (8));
      86  
      87    /* Verify that the built-in correctly detects the attribute on
      88       the type of the lvalue referenced by the pointer. */
      89    A (0, i8ptr,     aligned);
      90    A (0, i8ptr,     aligned (8));
      91    A (0, i8ptr + 1, aligned);
      92    A (0, i8ptr + 3, aligned (8));
      93    A (1, *i8ptr,    aligned);
      94    A (0, *i8ptr,    aligned (1));
      95    A (0, *i8ptr,    aligned (2));
      96    A (0, *i8ptr,    aligned (4));
      97    A (1, *i8ptr,    aligned (8));
      98    A (0, *i8ptr,    aligned (16));
      99  
     100    /* The reference itself is declared aligned, even though the type
     101       it refers to isn't.  But see PR c++/88362.  */
     102    A (1, ref, aligned);
     103    A (0, ref, aligned (1));
     104    A (0, ref, aligned (2));
     105    A (0, ref, aligned (4));
     106    A (1, ref, aligned (8));
     107    A (0, ref, aligned (16));
     108  
     109    /* Also verify that assignment expressions are accepted.  */
     110    A (0, ref = 1,  aligned);
     111    A (0, ref += 2, aligned (1));
     112    A (0, ref /= 3, aligned (8));
     113  
     114  }