aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg/Wstringop-overflow-60.c
blob: 8c9de20e9bc6ac4418a377780bc9c8cea59b0f6c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/* 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);
}