1 /* Test derived from Glibc's getifaddrs_internal. The code could be
2 rewritten to avoid the warning for the memcpy call but since unions
3 are designed to have their members treated as interchangeable there
4 isn't a whole lot to be gained from issuing one.
5 { dg-do compile }
6 { dg-options "-O2 -Wall" } */
7
8 typedef __SIZE_TYPE__ size_t;
9
10 extern void* memcpy (void*, const void*, size_t);
11
12 struct sockaddr
13 {
14 short sa_family;
15 char sa_data[14];
16 };
17
18 struct in_addr
19 {
20 int s_addr;
21 };
22
23 struct in6_addr
24 {
25 union
26 {
27 char __u6_addr8[16];
28 short __u6_addr16[8];
29 int __u6_addr32[4];
30 } __in6_u;
31 };
32
33 struct sockaddr_in
34 {
35 short sin_family;
36 short sin_port;
37 struct in_addr sin_addr;
38 unsigned char sin_zero[sizeof (struct sockaddr) -
39 (sizeof (short)) -
40 sizeof (short) -
41 sizeof (struct in_addr)];
42 };
43
44 struct sockaddr_in6
45 {
46 short sin6_family;
47 short sin6_port;
48 int sin6_flowinfo;
49 struct in6_addr sin6_addr;
50 int sin6_scope_id;
51 };
52
53 union
54 {
55 struct sockaddr sa;
56 struct sockaddr_in s4;
57 struct sockaddr_in6 s6;
58 } u1, u2;
59
60 struct sockaddr *sa;
61
62 void test_unconditional (void *p)
63 {
64 sa = &u1.sa;
65 memcpy (&((struct sockaddr_in6 *) sa)->sin6_addr, p, 16);
66 }
67
68 void test_conditional (void *p, int i)
69 {
70 sa = i ? &u1.sa : &u2.sa;
71 memcpy (&((struct sockaddr_in6 *) sa)->sin6_addr, p, 16);
72 }