1 /* PR middle-end/91582 - missing heap overflow detection for strcpy
2 PR middle-end/85484 - missing -Wstringop-overflow for strcpy with
3 a string of non-const length
5 { dg-options "-O2 -Wall -Wno-array-bounds" }
6 { dg-require-effective-target alloca } */
8 typedef __SIZE_TYPE__
size_t;
10 extern void* calloc (size_t, size_t);
11 extern void* malloc (size_t);
12 extern void* memcpy (void*, const void*, size_t);
13 extern void* memset (void*, int, size_t);
14 extern char* strcpy (char*, const char*);
15 extern size_t strlen (const char*);
20 void test_memcpy_nowarn (const void *s
, int i
, size_t n
)
22 sink (memcpy (calloc (1, 1), s
, 1));
23 sink (memcpy (calloc (1, 2), s
, 1));
24 sink (memcpy (calloc (2, 1), s
, 1));
25 sink (memcpy (calloc (3, 1), s
, 2));
26 sink (memcpy (calloc (3, 1), "12", 2));
27 sink (memcpy (calloc (3, 1), s
, 3));
28 sink (memcpy (calloc (3, 1), "12", 3));
29 sink (memcpy (calloc (i
, 1), s
, 1));
30 sink (memcpy (calloc (n
, 1), s
, 1));
31 sink (memcpy (calloc (1, n
), "", 1));
32 sink (memcpy (calloc (1, i
), "", 1));
33 sink (memcpy (calloc (i
, 1), "123", 3));
34 sink (memcpy (calloc (n
, 1), "123", 3));
35 sink (memcpy (calloc (1, i
), "123456", 7));
36 sink (memcpy (calloc (1, n
), "123456", 7));
37 sink (memcpy (calloc (n
, 1), s
, 12345));
38 sink (memcpy (calloc (1, n
), s
, n
- 1));
39 sink (memcpy (calloc (n
, 1), s
, n
));
41 sink (memcpy ((char*)calloc (1, 1) + i
, "123", 1));
42 sink (memcpy ((char*)calloc (n
, 1) + i
, "123", n
));
44 sink (memcpy ((char*)calloc (1, 1) + i
, s
, 1));
45 sink (memcpy ((char*)calloc (n
, 1) + i
, s
, n
));
47 sink (memcpy (malloc (1), s
, 1));
48 sink (memcpy (malloc (2), s
, 1));
49 sink (memcpy (malloc (3), s
, 2));
50 sink (memcpy (malloc (3), "12", 2));
51 sink (memcpy (malloc (3), s
, 3));
52 sink (memcpy (malloc (3), "12", 3));
53 sink (memcpy (malloc (n
), s
, 1));
54 sink (memcpy (malloc (n
), "", 1));
55 sink (memcpy (malloc (n
), "123", 3));
56 sink (memcpy (malloc (n
), "123456", 7));
57 sink (memcpy (malloc (n
), s
, 12345));
58 sink (memcpy (malloc (n
), s
, n
- 1));
59 sink (memcpy (malloc (n
), s
, n
));
62 const int a
[] = { 1, 2, 3, 4 };
63 void *p
= (char*)malloc (sizeof a
);
64 memcpy (p
, a
, sizeof a
);
69 const int a
[] = { 1, 2, 3, 4, 5 };
70 size_t nelts
= sizeof a
/ sizeof *a
;
72 memcpy (vla
, a
, nelts
* sizeof *vla
);
78 void test_memcpy_warn (const int *s
, size_t n
)
81 void *p
= (char*)malloc (0);
82 memcpy (p
, s
, 1); // { dg-warning "writing 1 byte into a region of size 0" }
87 void *p
= (char*)malloc (1);
88 memcpy (p
, s
, 2); // { dg-warning "writing 2 bytes into a region of size 1" }
93 void *p
= (char*)malloc (2);
94 memcpy (p
, s
, 3); // { dg-warning "writing 3 bytes into a region of size 2" }
99 void *p
= (char*)malloc (3);
100 memcpy (p
, s
, 4); // { dg-warning "writing 4 bytes into a region of size 3" }
105 const int a
[] = { 1, 2, 3, 4 };
106 void *p
= (char*)malloc (sizeof *a
);
107 memcpy (p
, a
, sizeof a
); // { dg-warning "" }
112 const int a
[] = { 1, 2, 3, 4, 5 };
113 size_t nelts
= sizeof a
/ sizeof *a
;
115 memcpy (vla
, a
, nelts
* sizeof *a
); // { dg-warning "" }
120 void *p
= malloc (n
);
121 memcpy (p
, s
, n
* sizeof *s
); // { dg-warning "\\\[-Wstringop-overflow" "" { xfail *-*-* } }
126 void test_memset_nowarn (int x
, size_t n
)
128 sink (memset (calloc (1, 1), x
, 1));
129 sink (memset (calloc (1, 2), x
, 1));
130 sink (memset (calloc (2, 1), x
, 1));
131 sink (memset (calloc (3, 1), x
, 2));
132 sink (memset (calloc (3, 1), x
, 3));
133 sink (memset (calloc (n
, 1), x
, 1));
134 sink (memset (calloc (n
, 1), x
, 12345));
135 sink (memset (calloc (1, n
), x
, n
- 1));
136 sink (memset (calloc (n
, 1), x
, n
));
138 sink (memset (malloc (1), x
, 1));
139 sink (memset (malloc (2), x
, 1));
140 sink (memset (malloc (3), x
, 2));
141 sink (memset (malloc (3), x
, 3));
142 sink (memset (malloc (n
), x
, 1));
143 sink (memset (malloc (n
), x
, 12345));
144 sink (memset (malloc (n
), x
, n
- 1));
145 sink (memset (malloc (n
), x
, n
));
148 const int a
[] = { 1, 2, 3, 4 };
149 void *p
= (char*)malloc (sizeof a
);
150 memset (p
, x
, sizeof a
);
155 const int a
[] = { 1, 2, 3, 4, 5 };
156 size_t nelts
= sizeof a
/ sizeof *a
;
158 memset (vla
, x
, nelts
* sizeof *vla
);
164 void test_memset_warn (int x
, size_t n
)
167 void *p
= (char*)malloc (0);
168 memset (p
, x
, 1); // { dg-warning "writing 1 byte into a region of size 0" }
173 void *p
= (char*)malloc (1);
174 memset (p
, x
, 2); // { dg-warning "writing 2 bytes into a region of size 1" }
179 void *p
= (char*)malloc (2);
180 memset (p
, x
, 3); // { dg-warning "writing 3 bytes into a region of size 2" }
185 void *p
= (char*)malloc (3);
186 memset (p
, x
, 4); // { dg-warning "writing 4 bytes into a region of size 3" }
191 const int a
[] = { 1, 2, 3, 4 };
192 void *p
= (char*)malloc (sizeof *a
);
193 memset (p
, 0, sizeof a
); // { dg-warning "" }
198 const int a
[] = { 1, 2, 3, 4, 5 };
199 size_t nelts
= sizeof a
/ sizeof *a
;
201 memset (vla
, 0, nelts
* sizeof *a
); // { dg-warning "" }
206 void *p
= malloc (n
);
207 memset (p
, x
, n
* sizeof (int)); // { dg-warning "\\\[-Wstringop-overflow" "" { xfail *-*-* } }
213 void test_strcpy_nowarn (const char *s
)
216 const char a
[] = "12";
218 char *t
= (char*)calloc (2, n
);
224 const char a
[] = "123";
225 unsigned n
= strlen (a
) + 1;
226 char *t
= (char*)calloc (n
, 1);
232 const char a
[] = "1234";
233 size_t n
= strlen (a
) * 2;
234 char *t
= (char*)malloc (n
);
240 const char a
[] = "1234";
241 size_t len
= strlen (a
) + 1;
248 size_t n
= strlen (s
) + 1;
249 char *t
= (char*)malloc (n
);
256 void test_strcpy_warn (const char *s
)
259 const char a
[] = "123";
260 /* Verify that using signed int for the strlen result works (i.e.,
261 that the conversion from signed int to size_t doesn't prevent
264 char *t
= (char*)calloc (n
, 1); // { dg-message "destination object of size 3 allocated by 'calloc'" "note" }
265 strcpy (t
, a
); // { dg-warning "writing 4 bytes into a region of size (between 0 and )?3 " }
271 const char a
[] = "1234";
272 size_t n
= strlen (a
);
273 char *t
= (char*)malloc (n
); // { dg-message "destination object of size 4 allocated by 'malloc'" "note" }
274 strcpy (t
, a
); // { dg-warning "writing 5 bytes into a region of size (between 0 and )?4 " }
278 // Exercise PR middle-end/85484.
280 size_t len
= strlen (s
);
281 char vla
[len
]; // { dg-message "destination object 'vla'" "vla note" }
282 strcpy (vla
, s
); // { dg-warning "writing one too many bytes into a region of a size that depends on 'strlen'" }
287 size_t n
= strlen (s
);
288 char *t
= (char*)malloc (n
); // { dg-message "allocated by 'malloc'" "malloc note" }
289 strcpy (t
, s
); // { dg-warning "writing one too many bytes into a region of a size that depends on 'strlen'" }