Merge with trank @ 137446
[official-gcc.git] / gcc / testsuite / gcc.c-torture / execute / builtins / lib / chk.c
blobe5197902b240cac47b1a0499c2a29a7957c0643c
1 #include <stdarg.h>
2 #ifdef __unix__
3 #include <sys/types.h>
4 #endif
6 extern void abort (void);
8 extern int inside_main;
9 void *chk_fail_buf[256] __attribute__((aligned (16)));
10 volatile int chk_fail_allowed, chk_calls;
11 volatile int memcpy_disallowed, mempcpy_disallowed, memmove_disallowed;
12 volatile int memset_disallowed, strcpy_disallowed, stpcpy_disallowed;
13 volatile int strncpy_disallowed, strcat_disallowed, strncat_disallowed;
14 volatile int sprintf_disallowed, vsprintf_disallowed;
15 volatile int snprintf_disallowed, vsnprintf_disallowed;
16 extern __SIZE_TYPE__ strlen (const char *);
17 extern int vsprintf (char *, const char *, va_list);
19 void __attribute__((noreturn))
20 __chk_fail (void)
22 if (chk_fail_allowed)
23 __builtin_longjmp (chk_fail_buf, 1);
24 abort ();
27 void *
28 memcpy (void *dst, const void *src, __SIZE_TYPE__ n)
30 const char *srcp;
31 char *dstp;
33 #ifdef __OPTIMIZE__
34 if (memcpy_disallowed && inside_main)
35 abort ();
36 #endif
38 srcp = src;
39 dstp = dst;
40 while (n-- != 0)
41 *dstp++ = *srcp++;
43 return dst;
46 void *
47 __memcpy_chk (void *dst, const void *src, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
49 /* If size is -1, GCC should always optimize the call into memcpy. */
50 if (size == (__SIZE_TYPE__) -1)
51 abort ();
52 ++chk_calls;
53 if (n > size)
54 __chk_fail ();
55 return memcpy (dst, src, n);
58 void *
59 mempcpy (void *dst, const void *src, __SIZE_TYPE__ n)
61 const char *srcp;
62 char *dstp;
64 #ifdef __OPTIMIZE__
65 if (mempcpy_disallowed && inside_main)
66 abort ();
67 #endif
69 srcp = src;
70 dstp = dst;
71 while (n-- != 0)
72 *dstp++ = *srcp++;
74 return dstp;
77 void *
78 __mempcpy_chk (void *dst, const void *src, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
80 /* If size is -1, GCC should always optimize the call into mempcpy. */
81 if (size == (__SIZE_TYPE__) -1)
82 abort ();
83 ++chk_calls;
84 if (n > size)
85 __chk_fail ();
86 return mempcpy (dst, src, n);
89 void *
90 memmove (void *dst, const void *src, __SIZE_TYPE__ n)
92 const char *srcp;
93 char *dstp;
95 #ifdef __OPTIMIZE__
96 if (memmove_disallowed && inside_main)
97 abort ();
98 #endif
100 srcp = src;
101 dstp = dst;
102 if (srcp < dstp)
103 while (n-- != 0)
104 dstp[n] = srcp[n];
105 else
106 while (n-- != 0)
107 *dstp++ = *srcp++;
109 return dst;
112 void *
113 __memmove_chk (void *dst, const void *src, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
115 /* If size is -1, GCC should always optimize the call into memmove. */
116 if (size == (__SIZE_TYPE__) -1)
117 abort ();
118 ++chk_calls;
119 if (n > size)
120 __chk_fail ();
121 return memmove (dst, src, n);
124 void *
125 memset (void *dst, int c, __SIZE_TYPE__ n)
127 /* Single-byte memsets should be done inline when optimisation
128 is enabled. */
129 #ifdef __OPTIMIZE__
130 if (memset_disallowed && inside_main && n < 2)
131 abort ();
132 #endif
134 while (n-- != 0)
135 n[(char *) dst] = c;
137 return dst;
140 void *
141 __memset_chk (void *dst, int c, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
143 /* If size is -1, GCC should always optimize the call into memset. */
144 if (size == (__SIZE_TYPE__) -1)
145 abort ();
146 ++chk_calls;
147 if (n > size)
148 __chk_fail ();
149 return memset (dst, c, n);
152 char *
153 strcpy (char *d, const char *s)
155 char *r = d;
156 #ifdef __OPTIMIZE__
157 if (strcpy_disallowed && inside_main)
158 abort ();
159 #endif
160 while ((*d++ = *s++));
161 return r;
164 char *
165 __strcpy_chk (char *d, const char *s, __SIZE_TYPE__ size)
167 /* If size is -1, GCC should always optimize the call into strcpy. */
168 if (size == (__SIZE_TYPE__) -1)
169 abort ();
170 ++chk_calls;
171 if (strlen (s) >= size)
172 __chk_fail ();
173 return strcpy (d, s);
176 char *
177 stpcpy (char *dst, const char *src)
179 #ifdef __OPTIMIZE__
180 if (stpcpy_disallowed && inside_main)
181 abort ();
182 #endif
184 while (*src != 0)
185 *dst++ = *src++;
187 *dst = 0;
188 return dst;
191 char *
192 __stpcpy_chk (char *d, const char *s, __SIZE_TYPE__ size)
194 /* If size is -1, GCC should always optimize the call into stpcpy. */
195 if (size == (__SIZE_TYPE__) -1)
196 abort ();
197 ++chk_calls;
198 if (strlen (s) >= size)
199 __chk_fail ();
200 return stpcpy (d, s);
203 char *
204 strncpy (char *s1, const char *s2, __SIZE_TYPE__ n)
206 char *dest = s1;
207 #ifdef __OPTIMIZE__
208 if (strncpy_disallowed && inside_main)
209 abort();
210 #endif
211 for (; *s2 && n; n--)
212 *s1++ = *s2++;
213 while (n--)
214 *s1++ = 0;
215 return dest;
218 char *
219 __strncpy_chk (char *s1, const char *s2, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
221 /* If size is -1, GCC should always optimize the call into strncpy. */
222 if (size == (__SIZE_TYPE__) -1)
223 abort ();
224 ++chk_calls;
225 if (n > size)
226 __chk_fail ();
227 return strncpy (s1, s2, n);
230 char *
231 strcat (char *dst, const char *src)
233 char *p = dst;
235 #ifdef __OPTIMIZE__
236 if (strcat_disallowed && inside_main)
237 abort ();
238 #endif
240 while (*p)
241 p++;
242 while ((*p++ = *src++))
244 return dst;
247 char *
248 __strcat_chk (char *d, const char *s, __SIZE_TYPE__ size)
250 /* If size is -1, GCC should always optimize the call into strcat. */
251 if (size == (__SIZE_TYPE__) -1)
252 abort ();
253 ++chk_calls;
254 if (strlen (d) + strlen (s) >= size)
255 __chk_fail ();
256 return strcat (d, s);
259 char *
260 strncat (char *s1, const char *s2, __SIZE_TYPE__ n)
262 char *dest = s1;
263 char c;
264 #ifdef __OPTIMIZE__
265 if (strncat_disallowed && inside_main)
266 abort();
267 #endif
268 while (*s1) s1++;
269 c = '\0';
270 while (n > 0)
272 c = *s2++;
273 *s1++ = c;
274 if (c == '\0')
275 return dest;
276 n--;
278 if (c != '\0')
279 *s1 = '\0';
280 return dest;
283 char *
284 __strncat_chk (char *d, const char *s, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
286 __SIZE_TYPE__ len = strlen (d), n1 = n;
287 const char *s1 = s;
289 /* If size is -1, GCC should always optimize the call into strncat. */
290 if (size == (__SIZE_TYPE__) -1)
291 abort ();
292 ++chk_calls;
293 while (len < size && n1 > 0)
295 if (*s1++ == '\0')
296 break;
297 ++len;
298 --n1;
301 if (len >= size)
302 __chk_fail ();
303 return strncat (d, s, n);
306 /* No chk test in GCC testsuite needs more bytes than this.
307 As we can't expect vsnprintf to be available on the target,
308 assume 4096 bytes is enough. */
309 static char chk_sprintf_buf[4096];
312 __sprintf_chk (char *str, int flag, __SIZE_TYPE__ size, const char *fmt, ...)
314 int ret;
315 va_list ap;
317 /* If size is -1 and flag 0, GCC should always optimize the call into
318 sprintf. */
319 if (size == (__SIZE_TYPE__) -1 && flag == 0)
320 abort ();
321 ++chk_calls;
322 #ifdef __OPTIMIZE__
323 if (sprintf_disallowed && inside_main)
324 abort();
325 #endif
326 va_start (ap, fmt);
327 ret = vsprintf (chk_sprintf_buf, fmt, ap);
328 va_end (ap);
329 if (ret >= 0)
331 if (ret >= size)
332 __chk_fail ();
333 memcpy (str, chk_sprintf_buf, ret + 1);
335 return ret;
339 __vsprintf_chk (char *str, int flag, __SIZE_TYPE__ size, const char *fmt,
340 va_list ap)
342 int ret;
344 /* If size is -1 and flag 0, GCC should always optimize the call into
345 vsprintf. */
346 if (size == (__SIZE_TYPE__) -1 && flag == 0)
347 abort ();
348 ++chk_calls;
349 #ifdef __OPTIMIZE__
350 if (vsprintf_disallowed && inside_main)
351 abort();
352 #endif
353 ret = vsprintf (chk_sprintf_buf, fmt, ap);
354 if (ret >= 0)
356 if (ret >= size)
357 __chk_fail ();
358 memcpy (str, chk_sprintf_buf, ret + 1);
360 return ret;
364 __snprintf_chk (char *str, __SIZE_TYPE__ len, int flag, __SIZE_TYPE__ size,
365 const char *fmt, ...)
367 int ret;
368 va_list ap;
370 /* If size is -1 and flag 0, GCC should always optimize the call into
371 snprintf. */
372 if (size == (__SIZE_TYPE__) -1 && flag == 0)
373 abort ();
374 ++chk_calls;
375 if (size < len)
376 __chk_fail ();
377 #ifdef __OPTIMIZE__
378 if (snprintf_disallowed && inside_main)
379 abort();
380 #endif
381 va_start (ap, fmt);
382 ret = vsprintf (chk_sprintf_buf, fmt, ap);
383 va_end (ap);
384 if (ret >= 0)
386 if (ret < len)
387 memcpy (str, chk_sprintf_buf, ret + 1);
388 else
390 memcpy (str, chk_sprintf_buf, len - 1);
391 str[len - 1] = '\0';
394 return ret;
398 __vsnprintf_chk (char *str, __SIZE_TYPE__ len, int flag, __SIZE_TYPE__ size,
399 const char *fmt, va_list ap)
401 int ret;
403 /* If size is -1 and flag 0, GCC should always optimize the call into
404 vsnprintf. */
405 if (size == (__SIZE_TYPE__) -1 && flag == 0)
406 abort ();
407 ++chk_calls;
408 if (size < len)
409 __chk_fail ();
410 #ifdef __OPTIMIZE__
411 if (vsnprintf_disallowed && inside_main)
412 abort();
413 #endif
414 ret = vsprintf (chk_sprintf_buf, fmt, ap);
415 if (ret >= 0)
417 if (ret < len)
418 memcpy (str, chk_sprintf_buf, ret + 1);
419 else
421 memcpy (str, chk_sprintf_buf, len - 1);
422 str[len - 1] = '\0';
425 return ret;
429 snprintf (char *str, __SIZE_TYPE__ len, const char *fmt, ...)
431 int ret;
432 va_list ap;
434 #ifdef __OPTIMIZE__
435 if (snprintf_disallowed && inside_main)
436 abort();
437 #endif
438 va_start (ap, fmt);
439 ret = vsprintf (chk_sprintf_buf, fmt, ap);
440 va_end (ap);
441 if (ret >= 0)
443 if (ret < len)
444 memcpy (str, chk_sprintf_buf, ret + 1);
445 else if (len)
447 memcpy (str, chk_sprintf_buf, len - 1);
448 str[len - 1] = '\0';
451 return ret;
454 /* uClibc's vsprintf calls vsnprintf. */
455 #ifndef __UCLIBC__
457 vsnprintf (char *str, __SIZE_TYPE__ len, const char *fmt, va_list ap)
459 int ret;
461 #ifdef __OPTIMIZE__
462 if (vsnprintf_disallowed && inside_main)
463 abort();
464 #endif
465 ret = vsprintf (chk_sprintf_buf, fmt, ap);
466 if (ret >= 0)
468 if (ret < len)
469 memcpy (str, chk_sprintf_buf, ret + 1);
470 else if (len)
472 memcpy (str, chk_sprintf_buf, len - 1);
473 str[len - 1] = '\0';
476 return ret;
478 #endif