annotate gcc/testsuite/gcc.dg/builtin-stringop-chk-6.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 04ced10e8804
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Test exercising -Wrawmem-overflow and -Wstringop-overflow warnings. */
kono
parents:
diff changeset
2 /* { dg-do compile } */
kono
parents:
diff changeset
3 /* { dg-options "-O2 -Wstringop-overflow=2" } */
kono
parents:
diff changeset
4
kono
parents:
diff changeset
5 #define offsetof(type, mem) __builtin_offsetof (type, mem)
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 /* Return the number of bytes from member MEM of TYPE to the end
kono
parents:
diff changeset
8 of object OBJ. */
kono
parents:
diff changeset
9 #define offsetfrom(type, obj, mem) (sizeof (obj) - offsetof (type, mem))
kono
parents:
diff changeset
10
kono
parents:
diff changeset
11
kono
parents:
diff changeset
12 typedef __SIZE_TYPE__ size_t;
kono
parents:
diff changeset
13 extern void* memcpy (void*, const void*, size_t);
kono
parents:
diff changeset
14 extern void* memset (void*, int, __SIZE_TYPE__);
kono
parents:
diff changeset
15
kono
parents:
diff changeset
16
kono
parents:
diff changeset
17 struct A { char a, b; };
kono
parents:
diff changeset
18 struct B { struct A a; char c, d; };
kono
parents:
diff changeset
19
kono
parents:
diff changeset
20 /* Function to call to "escape" pointers from tests below to prevent
kono
parents:
diff changeset
21 GCC from assuming the values of the objects they point to stay
kono
parents:
diff changeset
22 the unchanged. */
kono
parents:
diff changeset
23 void escape (void*, ...);
kono
parents:
diff changeset
24
kono
parents:
diff changeset
25 /* Function to "generate" a random number each time it's called. Declared
kono
parents:
diff changeset
26 (but not defined) and used to prevent GCC from making assumptions about
kono
parents:
diff changeset
27 their values based on the variables uses in the tested expressions. */
kono
parents:
diff changeset
28 size_t random_unsigned_value (void);
kono
parents:
diff changeset
29
kono
parents:
diff changeset
30 /* Return a random unsigned value between MIN and MAX. */
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 static inline size_t
kono
parents:
diff changeset
33 range (size_t min, size_t max)
kono
parents:
diff changeset
34 {
kono
parents:
diff changeset
35 const size_t val = random_unsigned_value ();
kono
parents:
diff changeset
36 return val < min || max < val ? min : val;
kono
parents:
diff changeset
37 }
kono
parents:
diff changeset
38
kono
parents:
diff changeset
39
kono
parents:
diff changeset
40 void test_memop_warn_object (const void *src)
kono
parents:
diff changeset
41 {
kono
parents:
diff changeset
42 unsigned n = range (17, 29);
kono
parents:
diff changeset
43
kono
parents:
diff changeset
44 struct A a[2];
kono
parents:
diff changeset
45
kono
parents:
diff changeset
46 /* At both -Wstringop-overflow=2, like at 1, the destination of functions
kono
parents:
diff changeset
47 that operate on raw memory is considered to be the whole array and its
kono
parents:
diff changeset
48 size is therefore sizeof a. */
kono
parents:
diff changeset
49 memcpy (&a[0], src, n); /* { dg-warning "writing between 17 and 29 bytes into a region of size 4 overflows the destination" } */
kono
parents:
diff changeset
50 escape (a);
kono
parents:
diff changeset
51 }
kono
parents:
diff changeset
52
kono
parents:
diff changeset
53 void test_memop_warn_subobject (const void *src)
kono
parents:
diff changeset
54 {
kono
parents:
diff changeset
55 unsigned n = range (17, 31);
kono
parents:
diff changeset
56
kono
parents:
diff changeset
57 struct B b[2];
kono
parents:
diff changeset
58
kono
parents:
diff changeset
59 /* At -Wrawmem-overflow=2 the destination is considered to be
kono
parents:
diff changeset
60 the member sobobject of the first array element and its size
kono
parents:
diff changeset
61 is therefore sizeof b[0].a. */
kono
parents:
diff changeset
62 memcpy (&b[0].a, src, n); /* { dg-warning "writing between 17 and 31 bytes into a region of size 8 overflows the destination" } */
kono
parents:
diff changeset
63
kono
parents:
diff changeset
64 escape (b);
kono
parents:
diff changeset
65 }
kono
parents:
diff changeset
66
kono
parents:
diff changeset
67 void test_memop_nowarn_subobject (void)
kono
parents:
diff changeset
68 {
kono
parents:
diff changeset
69 struct B b[2];
kono
parents:
diff changeset
70
kono
parents:
diff changeset
71 /* The following idiom of clearing multiple members of a struct
kono
parents:
diff changeset
72 has been seen in a few places in the Linux kernel. Verify
kono
parents:
diff changeset
73 that a warning is not issued for it. */
kono
parents:
diff changeset
74 memset (&b[0].c, 0, sizeof b[0] - offsetof (struct B, c));
kono
parents:
diff changeset
75
kono
parents:
diff changeset
76 escape (b);
kono
parents:
diff changeset
77 }
kono
parents:
diff changeset
78
kono
parents:
diff changeset
79 struct C { char a[3], b; };
kono
parents:
diff changeset
80 struct D { struct C c; char d, e; };
kono
parents:
diff changeset
81
kono
parents:
diff changeset
82 extern char* strncpy (char*, const char*, __SIZE_TYPE__);
kono
parents:
diff changeset
83
kono
parents:
diff changeset
84 void test_stringop_warn_object (const char *str)
kono
parents:
diff changeset
85 {
kono
parents:
diff changeset
86 unsigned n = range (2 * sizeof (struct D), 32);
kono
parents:
diff changeset
87
kono
parents:
diff changeset
88 struct C c[2];
kono
parents:
diff changeset
89
kono
parents:
diff changeset
90 /* Similarly, at -Wstringop-overflow=2 the destination is considered
kono
parents:
diff changeset
91 to be the array member of the first element of the array c and its
kono
parents:
diff changeset
92 size is therefore sizeof c[0].a. */
kono
parents:
diff changeset
93 strncpy (c[0].a, "123", n); /* { dg-warning "writing between 12 and 32 bytes into a region of size 3 overflows the destination" } */
kono
parents:
diff changeset
94 escape (c);
kono
parents:
diff changeset
95
kono
parents:
diff changeset
96 strncpy (c[0].a, str, n); /* { dg-warning "writing between 12 and 32 bytes into a region of size 3 overflows the destination" } */
kono
parents:
diff changeset
97 escape (c);
kono
parents:
diff changeset
98 }
kono
parents:
diff changeset
99
kono
parents:
diff changeset
100 void test_stringop_warn_subobject (const char *src)
kono
parents:
diff changeset
101 {
kono
parents:
diff changeset
102 unsigned n = range (2 * sizeof (struct D), 32);
kono
parents:
diff changeset
103
kono
parents:
diff changeset
104 struct D d[2];
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 /* Same as above. */
kono
parents:
diff changeset
107 strncpy (d[0].c.a, "123", n); /* { dg-warning "writing between 12 and 32 bytes into a region of size 3 overflows the destination" } */
kono
parents:
diff changeset
108 escape (d);
kono
parents:
diff changeset
109
kono
parents:
diff changeset
110 strncpy (d[0].c.a, src, n); /* { dg-warning "writing between 12 and 32 bytes into a region of size 3 overflows the destination" } */
kono
parents:
diff changeset
111 escape (d);
kono
parents:
diff changeset
112 }