(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
sso-16.c
       1  /* { dg-do run } */
       2  /* { dg-require-effective-target int32plus } */
       3  /* { dg-options "-O3" } */
       4  
       5  typedef __INT32_TYPE__ int32_t;
       6  
       7  #define BIG_ENDIAN   __attribute__((scalar_storage_order("big-endian")))
       8  
       9  /* host order version (little endian)*/
      10  struct _ip6_addr {
      11      union {
      12          char addr8[16];
      13          int32_t  addr32[4];
      14      } u;
      15  };
      16  
      17  typedef struct _ip6_addr t_ip6_addr;
      18  
      19  struct _net_addr {
      20      char is_v4;
      21      union {
      22          int32_t        addr;
      23          t_ip6_addr addr6;
      24      } u;
      25  };
      26  
      27  typedef struct _net_addr t_net_addr;
      28  
      29  /* big endian version */
      30  struct _be_ip6_addr {
      31      union {
      32          char addr8[16];
      33      } BIG_ENDIAN u;
      34  } BIG_ENDIAN;
      35  
      36  typedef struct _be_ip6_addr t_be_ip6_addr;
      37  
      38  struct _be_net_addr {
      39      char is_v4;
      40      union {
      41          t_be_ip6_addr addr6;
      42          int32_t           addr;
      43      } BIG_ENDIAN u;
      44  } BIG_ENDIAN;
      45  
      46  typedef struct _be_net_addr t_be_net_addr;
      47  
      48  /* convert */
      49  t_be_ip6_addr be_ip6_addr(const t_ip6_addr ip6)
      50  {
      51      t_be_ip6_addr rc = {
      52          .u.addr8[0] = ip6.u.addr8[0],
      53          .u.addr8[1] = ip6.u.addr8[1],
      54          .u.addr8[2] = ip6.u.addr8[2],
      55          .u.addr8[3] = ip6.u.addr8[3],
      56          .u.addr8[4] = ip6.u.addr8[4],
      57          .u.addr8[5] = ip6.u.addr8[5],
      58          .u.addr8[6] = ip6.u.addr8[6],
      59          .u.addr8[7] = ip6.u.addr8[7],
      60          .u.addr8[8] = ip6.u.addr8[8],
      61          .u.addr8[9] = ip6.u.addr8[9],
      62          .u.addr8[10] = ip6.u.addr8[10],
      63          .u.addr8[11] = ip6.u.addr8[11],
      64          .u.addr8[12] = ip6.u.addr8[12],
      65          .u.addr8[13] = ip6.u.addr8[13],
      66          .u.addr8[14] = ip6.u.addr8[14],
      67          .u.addr8[15] = ip6.u.addr8[15],
      68      };
      69      return rc;
      70  }
      71  
      72  t_be_net_addr __attribute__((noipa)) be_net_addr(const t_net_addr ip)
      73  {
      74      t_be_net_addr rc = {.is_v4 = ip.is_v4 };
      75      if (ip.is_v4) {
      76          rc.u.addr = ip.u.addr;
      77      } else {
      78          rc.u.addr6 = be_ip6_addr(ip.u.addr6);
      79      }
      80      return rc;
      81  }
      82  
      83  int main(void)
      84  {
      85      t_be_net_addr out = { };
      86  
      87      t_net_addr in = {
      88          .is_v4 = 0,
      89          .u.addr6.u.addr8 =
      90              { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }
      91      };
      92  
      93      out = be_net_addr(in);
      94  
      95      // actually first 4 bytes are swapped
      96      if (in.u.addr6.u.addr8[0] != out.u.addr6.u.addr8[0])
      97          __builtin_abort();
      98  
      99      return 0;
     100  }