| /* Test derived from Glibc's getifaddrs_internal. The code could be |
| rewritten to avoid the warning for the memcpy call but since unions |
| are designed to have their members treated as interchangeable there |
| isn't a whole lot to be gained from issuing one. |
| { dg-do compile } |
| { dg-options "-O2 -Wall" } */ |
| |
| typedef __SIZE_TYPE__ size_t; |
| |
| extern void* memcpy (void*, const void*, size_t); |
| |
| struct sockaddr |
| { |
| short sa_family; |
| char sa_data[14]; |
| }; |
| |
| struct in_addr |
| { |
| int s_addr; |
| }; |
| |
| struct in6_addr |
| { |
| union |
| { |
| char __u6_addr8[16]; |
| short __u6_addr16[8]; |
| int __u6_addr32[4]; |
| } __in6_u; |
| }; |
| |
| struct sockaddr_in |
| { |
| short sin_family; |
| short sin_port; |
| struct in_addr sin_addr; |
| unsigned char sin_zero[sizeof (struct sockaddr) - |
| (sizeof (short)) - |
| sizeof (short) - |
| sizeof (struct in_addr)]; |
| }; |
| |
| struct sockaddr_in6 |
| { |
| short sin6_family; |
| short sin6_port; |
| int sin6_flowinfo; |
| struct in6_addr sin6_addr; |
| int sin6_scope_id; |
| }; |
| |
| union |
| { |
| struct sockaddr sa; |
| struct sockaddr_in s4; |
| struct sockaddr_in6 s6; |
| } u1, u2; |
| |
| struct sockaddr *sa; |
| |
| void test_unconditional (void *p) |
| { |
| sa = &u1.sa; |
| memcpy (&((struct sockaddr_in6 *) sa)->sin6_addr, p, 16); |
| } |
| |
| void test_conditional (void *p, int i) |
| { |
| sa = i ? &u1.sa : &u2.sa; |
| memcpy (&((struct sockaddr_in6 *) sa)->sin6_addr, p, 16); |
| } |