Reverting merge from trunk
[official-gcc.git] / gcc / testsuite / gcc.c-torture / execute / builtins / lib / chk.c
blob9db60c8e3f4b2a3124c51e5cf4518817f6e7d91e
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, stpncpy_disallowed, strcat_disallowed;
14 volatile int strncat_disallowed, 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 stpncpy (char *dst, const char *src, __SIZE_TYPE__ n)
206 #ifdef __OPTIMIZE__
207 if (stpncpy_disallowed && inside_main)
208 abort ();
209 #endif
211 for (; *src && n; n--)
212 *dst++ = *src++;
214 char *ret = dst;
216 while (n--)
217 *dst++ = 0;
219 return ret;
223 char *
224 __stpncpy_chk (char *s1, const char *s2, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
226 /* If size is -1, GCC should always optimize the call into stpncpy. */
227 if (size == (__SIZE_TYPE__) -1)
228 abort ();
229 ++chk_calls;
230 if (n > size)
231 __chk_fail ();
232 return stpncpy (s1, s2, n);
235 char *
236 strncpy (char *s1, const char *s2, __SIZE_TYPE__ n)
238 char *dest = s1;
239 #ifdef __OPTIMIZE__
240 if (strncpy_disallowed && inside_main)
241 abort();
242 #endif
243 for (; *s2 && n; n--)
244 *s1++ = *s2++;
245 while (n--)
246 *s1++ = 0;
247 return dest;
250 char *
251 __strncpy_chk (char *s1, const char *s2, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
253 /* If size is -1, GCC should always optimize the call into strncpy. */
254 if (size == (__SIZE_TYPE__) -1)
255 abort ();
256 ++chk_calls;
257 if (n > size)
258 __chk_fail ();
259 return strncpy (s1, s2, n);
262 char *
263 strcat (char *dst, const char *src)
265 char *p = dst;
267 #ifdef __OPTIMIZE__
268 if (strcat_disallowed && inside_main)
269 abort ();
270 #endif
272 while (*p)
273 p++;
274 while ((*p++ = *src++))
276 return dst;
279 char *
280 __strcat_chk (char *d, const char *s, __SIZE_TYPE__ size)
282 /* If size is -1, GCC should always optimize the call into strcat. */
283 if (size == (__SIZE_TYPE__) -1)
284 abort ();
285 ++chk_calls;
286 if (strlen (d) + strlen (s) >= size)
287 __chk_fail ();
288 return strcat (d, s);
291 char *
292 strncat (char *s1, const char *s2, __SIZE_TYPE__ n)
294 char *dest = s1;
295 char c;
296 #ifdef __OPTIMIZE__
297 if (strncat_disallowed && inside_main)
298 abort();
299 #endif
300 while (*s1) s1++;
301 c = '\0';
302 while (n > 0)
304 c = *s2++;
305 *s1++ = c;
306 if (c == '\0')
307 return dest;
308 n--;
310 if (c != '\0')
311 *s1 = '\0';
312 return dest;
315 char *
316 __strncat_chk (char *d, const char *s, __SIZE_TYPE__ n, __SIZE_TYPE__ size)
318 __SIZE_TYPE__ len = strlen (d), n1 = n;
319 const char *s1 = s;
321 /* If size is -1, GCC should always optimize the call into strncat. */
322 if (size == (__SIZE_TYPE__) -1)
323 abort ();
324 ++chk_calls;
325 while (len < size && n1 > 0)
327 if (*s1++ == '\0')
328 break;
329 ++len;
330 --n1;
333 if (len >= size)
334 __chk_fail ();
335 return strncat (d, s, n);
338 /* No chk test in GCC testsuite needs more bytes than this.
339 As we can't expect vsnprintf to be available on the target,
340 assume 4096 bytes is enough. */
341 static char chk_sprintf_buf[4096];
344 __sprintf_chk (char *str, int flag, __SIZE_TYPE__ size, const char *fmt, ...)
346 int ret;
347 va_list ap;
349 /* If size is -1 and flag 0, GCC should always optimize the call into
350 sprintf. */
351 if (size == (__SIZE_TYPE__) -1 && flag == 0)
352 abort ();
353 ++chk_calls;
354 #ifdef __OPTIMIZE__
355 if (sprintf_disallowed && inside_main)
356 abort();
357 #endif
358 va_start (ap, fmt);
359 ret = vsprintf (chk_sprintf_buf, fmt, ap);
360 va_end (ap);
361 if (ret >= 0)
363 if (ret >= size)
364 __chk_fail ();
365 memcpy (str, chk_sprintf_buf, ret + 1);
367 return ret;
371 __vsprintf_chk (char *str, int flag, __SIZE_TYPE__ size, const char *fmt,
372 va_list ap)
374 int ret;
376 /* If size is -1 and flag 0, GCC should always optimize the call into
377 vsprintf. */
378 if (size == (__SIZE_TYPE__) -1 && flag == 0)
379 abort ();
380 ++chk_calls;
381 #ifdef __OPTIMIZE__
382 if (vsprintf_disallowed && inside_main)
383 abort();
384 #endif
385 ret = vsprintf (chk_sprintf_buf, fmt, ap);
386 if (ret >= 0)
388 if (ret >= size)
389 __chk_fail ();
390 memcpy (str, chk_sprintf_buf, ret + 1);
392 return ret;
396 __snprintf_chk (char *str, __SIZE_TYPE__ len, int flag, __SIZE_TYPE__ size,
397 const char *fmt, ...)
399 int ret;
400 va_list ap;
402 /* If size is -1 and flag 0, GCC should always optimize the call into
403 snprintf. */
404 if (size == (__SIZE_TYPE__) -1 && flag == 0)
405 abort ();
406 ++chk_calls;
407 if (size < len)
408 __chk_fail ();
409 #ifdef __OPTIMIZE__
410 if (snprintf_disallowed && inside_main)
411 abort();
412 #endif
413 va_start (ap, fmt);
414 ret = vsprintf (chk_sprintf_buf, fmt, ap);
415 va_end (ap);
416 if (ret >= 0)
418 if (ret < len)
419 memcpy (str, chk_sprintf_buf, ret + 1);
420 else
422 memcpy (str, chk_sprintf_buf, len - 1);
423 str[len - 1] = '\0';
426 return ret;
430 __vsnprintf_chk (char *str, __SIZE_TYPE__ len, int flag, __SIZE_TYPE__ size,
431 const char *fmt, va_list ap)
433 int ret;
435 /* If size is -1 and flag 0, GCC should always optimize the call into
436 vsnprintf. */
437 if (size == (__SIZE_TYPE__) -1 && flag == 0)
438 abort ();
439 ++chk_calls;
440 if (size < len)
441 __chk_fail ();
442 #ifdef __OPTIMIZE__
443 if (vsnprintf_disallowed && inside_main)
444 abort();
445 #endif
446 ret = vsprintf (chk_sprintf_buf, fmt, ap);
447 if (ret >= 0)
449 if (ret < len)
450 memcpy (str, chk_sprintf_buf, ret + 1);
451 else
453 memcpy (str, chk_sprintf_buf, len - 1);
454 str[len - 1] = '\0';
457 return ret;
461 snprintf (char *str, __SIZE_TYPE__ len, const char *fmt, ...)
463 int ret;
464 va_list ap;
466 #ifdef __OPTIMIZE__
467 if (snprintf_disallowed && inside_main)
468 abort();
469 #endif
470 va_start (ap, fmt);
471 ret = vsprintf (chk_sprintf_buf, fmt, ap);
472 va_end (ap);
473 if (ret >= 0)
475 if (ret < len)
476 memcpy (str, chk_sprintf_buf, ret + 1);
477 else if (len)
479 memcpy (str, chk_sprintf_buf, len - 1);
480 str[len - 1] = '\0';
483 return ret;
486 /* uClibc's vsprintf calls vsnprintf. */
487 #ifndef __UCLIBC__
489 vsnprintf (char *str, __SIZE_TYPE__ len, const char *fmt, va_list ap)
491 int ret;
493 #ifdef __OPTIMIZE__
494 if (vsnprintf_disallowed && inside_main)
495 abort();
496 #endif
497 ret = vsprintf (chk_sprintf_buf, fmt, ap);
498 if (ret >= 0)
500 if (ret < len)
501 memcpy (str, chk_sprintf_buf, ret + 1);
502 else if (len)
504 memcpy (str, chk_sprintf_buf, len - 1);
505 str[len - 1] = '\0';
508 return ret;
510 #endif