annotate gcc/testsuite/gcc.dg/builtin-stringop-chk-8.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Test exercising -Wstringop-overflow warnings for reading past the end. */
kono
parents:
diff changeset
2 /* { dg-do compile } */
kono
parents:
diff changeset
3 /* { dg-options "-O2 -Wstringop-overflow=1 -ftrack-macro-expansion=0" } */
kono
parents:
diff changeset
4
kono
parents:
diff changeset
5 #define PTRDIFF_MAX __PTRDIFF_MAX__
kono
parents:
diff changeset
6 #define SIZE_MAX __SIZE_MAX__
kono
parents:
diff changeset
7
kono
parents:
diff changeset
8 #define offsetof(type, mem) __builtin_offsetof (type, mem)
kono
parents:
diff changeset
9
kono
parents:
diff changeset
10 /* Return the number of bytes from member MEM of TYPE to the end
kono
parents:
diff changeset
11 of object OBJ. */
kono
parents:
diff changeset
12 #define offsetfrom(type, obj, mem) (sizeof (obj) - offsetof (type, mem))
kono
parents:
diff changeset
13
kono
parents:
diff changeset
14
kono
parents:
diff changeset
15 typedef __SIZE_TYPE__ size_t;
kono
parents:
diff changeset
16 extern void* memchr (const void*, int, size_t);
kono
parents:
diff changeset
17 extern int memcmp (const void*, const void*, size_t);
kono
parents:
diff changeset
18 extern void* memcpy (void*, const void*, size_t);
kono
parents:
diff changeset
19 extern void* memmove (void*, const void*, size_t);
kono
parents:
diff changeset
20 extern void* mempcpy (void*, const void*, size_t);
kono
parents:
diff changeset
21
kono
parents:
diff changeset
22 #define memchr(d, s, n) sink (memchr (d, s, n))
kono
parents:
diff changeset
23 #define memcmp(d, s, n) sink (d, memcmp (d, s, n))
kono
parents:
diff changeset
24 #define memcpy(d, s, n) sink (memcpy (d, s, n))
kono
parents:
diff changeset
25 #define memmove(d, s, n) sink (memmove (d, s, n))
kono
parents:
diff changeset
26 #define mempcpy(d, s, n) sink (mempcpy (d, s, n))
kono
parents:
diff changeset
27
kono
parents:
diff changeset
28 struct A { char a, b; };
kono
parents:
diff changeset
29 struct B { struct A a; char c, d; };
kono
parents:
diff changeset
30
kono
parents:
diff changeset
31 /* Function to call to "escape" pointers from tests below to prevent
kono
parents:
diff changeset
32 GCC from assuming the values of the objects they point to stay
kono
parents:
diff changeset
33 the unchanged. */
kono
parents:
diff changeset
34 void sink (void*, ...);
kono
parents:
diff changeset
35
kono
parents:
diff changeset
36 /* Function to "generate" a random number each time it's called. Declared
kono
parents:
diff changeset
37 (but not defined) and used to prevent GCC from making assumptions about
kono
parents:
diff changeset
38 their values based on the variables uses in the tested expressions. */
kono
parents:
diff changeset
39 size_t random_unsigned_value (void);
kono
parents:
diff changeset
40
kono
parents:
diff changeset
41 /* Return a random unsigned value between MIN and MAX. */
kono
parents:
diff changeset
42
kono
parents:
diff changeset
43 static inline size_t
kono
parents:
diff changeset
44 range (size_t min, size_t max)
kono
parents:
diff changeset
45 {
kono
parents:
diff changeset
46 const size_t val = random_unsigned_value ();
kono
parents:
diff changeset
47 return val < min || max < val ? min : val;
kono
parents:
diff changeset
48 }
kono
parents:
diff changeset
49
kono
parents:
diff changeset
50 #define R(min, max) range (min, max)
kono
parents:
diff changeset
51
kono
parents:
diff changeset
52 /* Verify that reading beyond the end of a local array is diagnosed. */
kono
parents:
diff changeset
53
kono
parents:
diff changeset
54 void test_memop_warn_local (void *p, const void *q)
kono
parents:
diff changeset
55 {
kono
parents:
diff changeset
56 memcpy (p, "1234", R (6, 7)); /* { dg-warning "reading between 6 and 7 bytes from a region of size 5" } */
kono
parents:
diff changeset
57
kono
parents:
diff changeset
58 struct A a[2];
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 memcpy (p, a, R (7, 8)); /* { dg-warning "reading between 7 and 8 bytes from a region of size 4" } */
kono
parents:
diff changeset
61
kono
parents:
diff changeset
62 /* At -Wstringop-overflow=1 the destination is considered to be
kono
parents:
diff changeset
63 the whole array and its size is therefore sizeof a. */
kono
parents:
diff changeset
64 memcpy (p, &a[0], R (8, 9)); /* { dg-warning "reading between 8 and 9 bytes from a region of size 4" } */
kono
parents:
diff changeset
65
kono
parents:
diff changeset
66 /* Verify the same as above but by reading from the first mmeber
kono
parents:
diff changeset
67 of the first element of the array. */
kono
parents:
diff changeset
68 memcpy (p, &a[0].a, R (8, 9)); /* { dg-warning "reading between 8 and 9 bytes from a region of size 4" } */
kono
parents:
diff changeset
69
kono
parents:
diff changeset
70 struct B b[2];
kono
parents:
diff changeset
71
kono
parents:
diff changeset
72 memcpy (p, &b[0], R (12, 32)); /* { dg-warning "reading between 12 and 32 bytes from a region of size 8" } */
kono
parents:
diff changeset
73
kono
parents:
diff changeset
74 /* Verify memchr/memcmp. */
kono
parents:
diff changeset
75 int i = R (0, 255);
kono
parents:
diff changeset
76 memchr ("", i, 2); /* { dg-warning "reading 2 bytes from a region of size 1" } */
kono
parents:
diff changeset
77 memchr ("", i, 2); /* { dg-warning "reading 2 bytes from a region of size 1" } */
kono
parents:
diff changeset
78 memchr ("123", i, 5); /* { dg-warning "reading 5 bytes from a region of size 4" } */
kono
parents:
diff changeset
79 memchr (a, i, sizeof a + 1); /* { dg-warning "reading 5 bytes from a region of size 4" } */
kono
parents:
diff changeset
80
kono
parents:
diff changeset
81 memcmp (p, "", 2); /* { dg-warning "reading 2 bytes from a region of size 1" } */
kono
parents:
diff changeset
82 memcmp (p, "123", 5); /* { dg-warning "reading 5 bytes from a region of size 4" } */
kono
parents:
diff changeset
83 memcmp (p, a, sizeof a + 1); /* { dg-warning "reading 5 bytes from a region of size 4" } */
kono
parents:
diff changeset
84
kono
parents:
diff changeset
85 size_t n = PTRDIFF_MAX + (size_t)1;
kono
parents:
diff changeset
86 memchr (p, 1, n); /* { dg-warning "exceeds maximum object size" } */
kono
parents:
diff changeset
87 memcmp (p, q, n); /* { dg-warning "exceeds maximum object size" } */
kono
parents:
diff changeset
88
kono
parents:
diff changeset
89 n = SIZE_MAX;
kono
parents:
diff changeset
90 memchr (p, 1, n); /* { dg-warning "exceeds maximum object size" } */
kono
parents:
diff changeset
91 memcmp (p, q, n); /* { dg-warning "exceeds maximum object size" } */
kono
parents:
diff changeset
92 }
kono
parents:
diff changeset
93
kono
parents:
diff changeset
94 /* Verify that reading beyond the end of a dynamically allocated array
kono
parents:
diff changeset
95 of known size is diagnosed. */
kono
parents:
diff changeset
96
kono
parents:
diff changeset
97 void test_memop_warn_alloc (void *p)
kono
parents:
diff changeset
98 {
kono
parents:
diff changeset
99 size_t n;
kono
parents:
diff changeset
100
kono
parents:
diff changeset
101 n = range (8, 32);
kono
parents:
diff changeset
102
kono
parents:
diff changeset
103 struct A *a = __builtin_malloc (sizeof *a * 2);
kono
parents:
diff changeset
104
kono
parents:
diff changeset
105 memcpy (p, a, n); /* { dg-warning "reading between 8 and 32 bytes from region of size 4" "memcpy from allocated" { xfail *-*-*} } */
kono
parents:
diff changeset
106
kono
parents:
diff changeset
107 memcpy (p, &a[0], n); /* { dg-warning "reading between 8 and 32 bytes from a region of size 4" "memcpy from allocated" { xfail *-*-*} } */
kono
parents:
diff changeset
108
kono
parents:
diff changeset
109 memcpy (p, &a[0].a, n); /* { dg-warning "reading between 8 and 32 bytes from a region of size 4" "memcpy from allocated" { xfail *-*-*} } */
kono
parents:
diff changeset
110
kono
parents:
diff changeset
111 n = range (12, 32);
kono
parents:
diff changeset
112
kono
parents:
diff changeset
113 struct B *b = __builtin_malloc (sizeof *b * 2);
kono
parents:
diff changeset
114
kono
parents:
diff changeset
115 memcpy (p, &b[0], n); /* { dg-warning "reading between 12 and 32 bytes from a region of size 8" "memcpy from allocated" { xfail *-*-*} } */
kono
parents:
diff changeset
116
kono
parents:
diff changeset
117 /* Verify memchr/memcmp. */
kono
parents:
diff changeset
118 n = sizeof *b * 2 + 1;
kono
parents:
diff changeset
119
kono
parents:
diff changeset
120 memchr (b, 1, n); /* { dg-warning "reading 5 bytes from a region of size 4" "memcmp from allocated" { xfail *-*-* } } */
kono
parents:
diff changeset
121 memcmp (p, b, n); /* { dg-warning "reading 5 bytes from a region of size 4" "memcmp from allocated" { xfail *-*-* } } */
kono
parents:
diff changeset
122 }
kono
parents:
diff changeset
123
kono
parents:
diff changeset
124
kono
parents:
diff changeset
125 void test_memop_nowarn (void *p)
kono
parents:
diff changeset
126 {
kono
parents:
diff changeset
127 struct B b[2];
kono
parents:
diff changeset
128
kono
parents:
diff changeset
129 size_t n = range (sizeof b, 32);
kono
parents:
diff changeset
130
kono
parents:
diff changeset
131 /* Verify that copying the whole array is not diagnosed regardless
kono
parents:
diff changeset
132 of whether the expression pointing to its beginning is obtained
kono
parents:
diff changeset
133 from the array itself or its first member(s). */
kono
parents:
diff changeset
134 memcpy (p, b, n);
kono
parents:
diff changeset
135
kono
parents:
diff changeset
136 memcpy (p, &b[0], n);
kono
parents:
diff changeset
137
kono
parents:
diff changeset
138 memcpy (p, &b[0].a, n);
kono
parents:
diff changeset
139
kono
parents:
diff changeset
140 memcpy (p, &b[0].a.a, n);
kono
parents:
diff changeset
141
kono
parents:
diff changeset
142 /* Verify that memchr/memcmp doesn't cause a warning. */
kono
parents:
diff changeset
143 memchr (p, 1, n);
kono
parents:
diff changeset
144 memchr (b, 2, n);
kono
parents:
diff changeset
145 memchr (&b[0], 3, n);
kono
parents:
diff changeset
146 memchr (&b[0].a, 4, n);
kono
parents:
diff changeset
147 memchr (&b[0].a.a, 5, n);
kono
parents:
diff changeset
148 memchr ("01234567", R (0, 255), n);
kono
parents:
diff changeset
149
kono
parents:
diff changeset
150 memcmp (p, p, n);
kono
parents:
diff changeset
151 memcmp (p, b, n);
kono
parents:
diff changeset
152 memcmp (p, &b[0], n);
kono
parents:
diff changeset
153 memcmp (p, &b[0].a, n);
kono
parents:
diff changeset
154 memcmp (p, &b[0].a.a, n);
kono
parents:
diff changeset
155 memcmp (p, "01234567", n);
kono
parents:
diff changeset
156 }
kono
parents:
diff changeset
157
kono
parents:
diff changeset
158
kono
parents:
diff changeset
159 /* The following function could specify in its API that it takes
kono
parents:
diff changeset
160 an array of exactly two elements, as shown below (or simply be
kono
parents:
diff changeset
161 called with such an array). Verify that reading from both
kono
parents:
diff changeset
162 elements is not diagnosed. */
kono
parents:
diff changeset
163 void test_memop_nowarn_arg (void*, const struct A[2]);
kono
parents:
diff changeset
164
kono
parents:
diff changeset
165 void test_memop_nowarn_arg (void *p, const struct A *a)
kono
parents:
diff changeset
166 {
kono
parents:
diff changeset
167 memcpy (p, a, 2 * sizeof *a);
kono
parents:
diff changeset
168
kono
parents:
diff changeset
169 memcpy (p, a, range (2 * sizeof *a, 123));
kono
parents:
diff changeset
170
kono
parents:
diff changeset
171 memchr (p, 1, 1234);
kono
parents:
diff changeset
172 memcmp (p, a, 1234);
kono
parents:
diff changeset
173 }