1 /* Verify that non-constant offsets don't suppress warnings in cases
2    when the size of the access alone makes it invalid, regardless of
3    the offset value.
4    Also verify that writing into unknown objects through pointers
5    (or pointer members) doesn't trigger warnings.
6    { dg-do compile }
7    { dg-options "-O1 -Wall -Wno-array-bounds" } */
8 
9 typedef __SIZE_TYPE__ size_t;
10 
11 extern void* memcpy (void*, const void*, size_t);
12 extern void* memset (void*, int, size_t);
13 
14 
15 struct Xp { char *p; } xp;
16 struct Xa { char *a[2]; } xa;
17 
nowarn_copy_read_pointed_obj_plus_cst(void * d)18 void nowarn_copy_read_pointed_obj_plus_cst (void *d)
19 {
20   int i = 0;
21   memcpy (d, xp.p + i, 9);
22   memcpy (d, xa.a[i], 9);
23 }
24 
nowarn_copy_read_pointed_obj_plus_var(void * d,int i)25 void nowarn_copy_read_pointed_obj_plus_var (void *d, int i)
26 {
27   memcpy (d, xp.p + i, 9);
28   memcpy (d, xa.a[i], 9);
29 }
30 
31 
warn_copy_read_pointer_plus_cst(void * d)32 void warn_copy_read_pointer_plus_cst (void *d)
33 {
34   int i = 0;
35   memcpy (d, &xp.p + i, 9);   // { dg-warning "reading 9 bytes from a region of size . " }
36 }
37 
warn_copy_read_pointer_plus_var(void * d,int i)38 void warn_copy_read_pointer_plus_var (void *d, int i)
39 {
40   memcpy (d, &xp.p + i, 9);   // { dg-warning "reading 9 bytes from a region of size . " }
41 }
42 
43 
nowarn_copy_write_pointed_obj_plus_cst(const void * s)44 void nowarn_copy_write_pointed_obj_plus_cst (const void *s)
45 {
46   int i = 0;
47   memcpy (xp.p + i, s, 9);
48   memcpy (xa.a[i], s, 9);
49 }
50 
nowarn_copy_write_pointed_obj_plus_var(const void * s,int i)51 void nowarn_copy_write_pointed_obj_plus_var (const void *s, int i)
52 {
53   memcpy (xp.p + i, s, 9);
54   memcpy (xa.a[i], s, 9);
55 }
56 
57 
warn_copy_write_pointer_plus_cst(const void * s)58 void warn_copy_write_pointer_plus_cst (const void *s)
59 {
60   int i = 0;
61   memcpy (&xp.p + i, s, 9);   // { dg-warning "writing 9 bytes into a region of size . " }
62 }
63 
warn_copy_write_pointer_plus_var(const void * s,int i)64 void warn_copy_write_pointer_plus_var (const void *s, int i)
65 {
66   memcpy (&xp.p + i, s, 9);   // { dg-warning "writing 9 bytes into a region of size . " }
67 }
68 
69 
nowarn_set_pointed_obj_plus_cst(void)70 void nowarn_set_pointed_obj_plus_cst (void)
71 {
72   int i = 0;
73   memset (xp.p + i, 0, 9);
74   memset (xa.a[i], 0, 9);
75 }
76 
nowarn_set_pointed_obj_plus_var(int i)77 void nowarn_set_pointed_obj_plus_var (int i)
78 {
79   memset (xp.p + i, 0, 9);
80   memset (xa.a[i], 0, 9);
81 }
82 
83 
warn_set_pointer_plus_cst(void)84 void warn_set_pointer_plus_cst (void)
85 {
86   int i = 0;
87   memset (&xp.p + i, 0, 9);   // { dg-warning "writing 9 bytes into a region of size . " }
88 }
89 
warn_set_pointer_plus_var(int i)90 void warn_set_pointer_plus_var (int i)
91 {
92   memset (&xp.p + i, 0, 9);   // { dg-warning "writing 9 bytes into a region of size . " }
93   memset (&xa.a[i], 0, 17);   // { dg-warning "writing 17 bytes into a region of size \[0-9\]+ " }
94 }
95