1 /* Copyright (C) 2004, 2005 Free Software Foundation.
3 Ensure builtin __memset_chk performs correctly. */
5 extern void abort (void);
6 typedef __SIZE_TYPE__
size_t;
7 extern size_t strlen(const char *);
8 extern void *memcpy (void *, const void *, size_t);
9 extern void *memset (void *, int, size_t);
10 extern int memcmp (const void *, const void *, size_t);
21 __attribute__((noinline
))
24 memset_disallowed
= 1;
26 memset (buffer
, argc
, 0);
27 memset (buffer
, argc
, 1);
28 memset (buffer
, argc
, 2);
29 memset (buffer
, argc
, 3);
30 memset (buffer
, argc
, 4);
31 memset (buffer
, argc
, 5);
32 memset (buffer
, argc
, 6);
33 memset (buffer
, argc
, 7);
34 memset (buffer
, argc
, 8);
35 memset (buffer
, argc
, 9);
36 memset (buffer
, argc
, 10);
37 memset (buffer
, argc
, 11);
38 memset (buffer
, argc
, 12);
39 memset (buffer
, argc
, 13);
40 memset (buffer
, argc
, 14);
41 memset (buffer
, argc
, 15);
42 memset (buffer
, argc
, 16);
43 memset (buffer
, argc
, 17);
44 memset_disallowed
= 0;
49 /* Test whether compile time checking is done where it should
50 and so is runtime object size checking. */
52 __attribute__((noinline
))
55 struct A
{ char buf1
[10]; char buf2
[10]; } a
;
56 char *r
= l1
== 1 ? &a
.buf1
[5] : &a
.buf2
[4];
61 /* The following calls should do runtime checking
62 - length is not known, but destination is. */
64 memset (a
.buf1
+ 2, 'a', l1
);
65 memset (r
, '\0', l1
+ 1);
66 r
= l1
== 1 ? __builtin_alloca (4) : &a
.buf2
[7];
67 memset (r
, argc
, l1
+ 2);
68 memset (r
+ 2, 'Q', l1
);
70 for (i
= 0; i
< 4; ++i
)
85 /* Following have known destination and known length,
86 so if optimizing certainly shouldn't result in the checking
89 memset (a
.buf1
+ 2, '\0', 1);
91 r
= l1
== 1 ? __builtin_alloca (4) : &a
.buf2
[7];
95 for (i
= 0; i
< 4; ++i
)
98 r
= &a
.buf1
[1], l
= 2;
100 r
= &a
.buf2
[7], l
= 3;
101 else if (i
== l1
+ 1)
103 else if (i
== l1
+ 2)
104 r
= &a
.buf1
[9], l
= 1;
107 /* Here, l is known to be at most 4 and __builtin_object_size (&buf3[16], 0)
108 is 4, so this doesn't need runtime checking. */
109 memset (&buf3
[16], 'd', l
);
110 /* Neither length nor destination known. Doesn't need runtime checking. */
111 memset (s4
, 'a', l1
);
112 memset (s4
+ 2, '\0', l1
+ 2);
113 /* Destination unknown. */
114 memset (s4
+ 4, 'b', 2);
115 memset (s4
+ 6, '\0', 4);
121 /* Test whether runtime and/or compile time checking catches
124 __attribute__((noinline
))
127 struct A
{ char buf1
[10]; char buf2
[10]; } a
;
130 chk_fail_allowed
= 1;
131 /* Runtime checks. */
132 if (__builtin_setjmp (chk_fail_buf
) == 0)
134 memset (&a
.buf2
[9], '\0', l1
+ 1);
137 if (__builtin_setjmp (chk_fail_buf
) == 0)
139 memset (&a
.buf2
[7], 'T', strlen (s3
) + 1);
142 /* This should be detectable at compile time already. */
143 if (__builtin_setjmp (chk_fail_buf
) == 0)
145 memset (&buf3
[19], 'b', 2);
148 chk_fail_allowed
= 0;
152 #define MAX_OFFSET (sizeof (long long))
156 #define MAX_COPY (10 * sizeof (long long))
159 #define MAX_COPY2 MAX_COPY
163 #define MAX_EXTRA (sizeof (long long))
166 #define MAX_LENGTH (MAX_OFFSET + MAX_COPY + MAX_EXTRA)
167 #define MAX_LENGTH2 (MAX_OFFSET + MAX_COPY2 + MAX_EXTRA)
170 char buf
[MAX_LENGTH
];
172 long double align_fp
;
178 __attribute__((noinline
))
184 for (off
= 0; off
< MAX_OFFSET
; off
++)
185 for (len
= 1; len
< MAX_COPY
; len
++)
187 for (i
= 0; i
< MAX_LENGTH
; i
++)
190 p
= memset (u
.buf
+ off
, '\0', len
);
191 if (p
!= u
.buf
+ off
)
195 for (i
= 0; i
< off
; i
++, q
++)
199 for (i
= 0; i
< len
; i
++, q
++)
203 for (i
= 0; i
< MAX_EXTRA
; i
++, q
++)
207 p
= memset (u
.buf
+ off
, A
, len
);
208 if (p
!= u
.buf
+ off
)
212 for (i
= 0; i
< off
; i
++, q
++)
216 for (i
= 0; i
< len
; i
++, q
++)
220 for (i
= 0; i
< MAX_EXTRA
; i
++, q
++)
224 p
= memset (u
.buf
+ off
, 'B', len
);
225 if (p
!= u
.buf
+ off
)
229 for (i
= 0; i
< off
; i
++, q
++)
233 for (i
= 0; i
< len
; i
++, q
++)
237 for (i
= 0; i
< MAX_EXTRA
; i
++, q
++)
244 char buf
[MAX_LENGTH2
];
246 long double align_fp
;
253 for (i
= 0; i
< MAX_LENGTH2
; i
++)
257 void check (int off
, int len
, int ch
)
263 for (i
= 0; i
< off
; i
++, q
++)
267 for (i
= 0; i
< len
; i
++, q
++)
271 for (i
= 0; i
< MAX_EXTRA
; i
++, q
++)
277 __attribute__((noinline
))
284 for (off
= 0; off
< MAX_OFFSET
; off
++)
288 p
= memset (u2
.buf
+ off
, '\0', 1);
289 if (p
!= u2
.buf
+ off
) abort ();
290 check (off
, 1, '\0');
292 p
= memset (u2
.buf
+ off
, A
, 1);
293 if (p
!= u2
.buf
+ off
) abort ();
296 p
= memset (u2
.buf
+ off
, 'B', 1);
297 if (p
!= u2
.buf
+ off
) abort ();
302 for (off
= 0; off
< MAX_OFFSET
; off
++)
306 p
= memset (u2
.buf
+ off
, '\0', 2);
307 if (p
!= u2
.buf
+ off
) abort ();
308 check (off
, 2, '\0');
310 p
= memset (u2
.buf
+ off
, A
, 2);
311 if (p
!= u2
.buf
+ off
) abort ();
314 p
= memset (u2
.buf
+ off
, 'B', 2);
315 if (p
!= u2
.buf
+ off
) abort ();
320 for (off
= 0; off
< MAX_OFFSET
; off
++)
324 p
= memset (u2
.buf
+ off
, '\0', 3);
325 if (p
!= u2
.buf
+ off
) abort ();
326 check (off
, 3, '\0');
328 p
= memset (u2
.buf
+ off
, A
, 3);
329 if (p
!= u2
.buf
+ off
) abort ();
332 p
= memset (u2
.buf
+ off
, 'B', 3);
333 if (p
!= u2
.buf
+ off
) abort ();
338 for (off
= 0; off
< MAX_OFFSET
; off
++)
342 p
= memset (u2
.buf
+ off
, '\0', 4);
343 if (p
!= u2
.buf
+ off
) abort ();
344 check (off
, 4, '\0');
346 p
= memset (u2
.buf
+ off
, A
, 4);
347 if (p
!= u2
.buf
+ off
) abort ();
350 p
= memset (u2
.buf
+ off
, 'B', 4);
351 if (p
!= u2
.buf
+ off
) abort ();
356 for (off
= 0; off
< MAX_OFFSET
; off
++)
360 p
= memset (u2
.buf
+ off
, '\0', 5);
361 if (p
!= u2
.buf
+ off
) abort ();
362 check (off
, 5, '\0');
364 p
= memset (u2
.buf
+ off
, A
, 5);
365 if (p
!= u2
.buf
+ off
) abort ();
368 p
= memset (u2
.buf
+ off
, 'B', 5);
369 if (p
!= u2
.buf
+ off
) abort ();
374 for (off
= 0; off
< MAX_OFFSET
; off
++)
378 p
= memset (u2
.buf
+ off
, '\0', 6);
379 if (p
!= u2
.buf
+ off
) abort ();
380 check (off
, 6, '\0');
382 p
= memset (u2
.buf
+ off
, A
, 6);
383 if (p
!= u2
.buf
+ off
) abort ();
386 p
= memset (u2
.buf
+ off
, 'B', 6);
387 if (p
!= u2
.buf
+ off
) abort ();
392 for (off
= 0; off
< MAX_OFFSET
; off
++)
396 p
= memset (u2
.buf
+ off
, '\0', 7);
397 if (p
!= u2
.buf
+ off
) abort ();
398 check (off
, 7, '\0');
400 p
= memset (u2
.buf
+ off
, A
, 7);
401 if (p
!= u2
.buf
+ off
) abort ();
404 p
= memset (u2
.buf
+ off
, 'B', 7);
405 if (p
!= u2
.buf
+ off
) abort ();
410 for (off
= 0; off
< MAX_OFFSET
; off
++)
414 p
= memset (u2
.buf
+ off
, '\0', 8);
415 if (p
!= u2
.buf
+ off
) abort ();
416 check (off
, 8, '\0');
418 p
= memset (u2
.buf
+ off
, A
, 8);
419 if (p
!= u2
.buf
+ off
) abort ();
422 p
= memset (u2
.buf
+ off
, 'B', 8);
423 if (p
!= u2
.buf
+ off
) abort ();
428 for (off
= 0; off
< MAX_OFFSET
; off
++)
432 p
= memset (u2
.buf
+ off
, '\0', 9);
433 if (p
!= u2
.buf
+ off
) abort ();
434 check (off
, 9, '\0');
436 p
= memset (u2
.buf
+ off
, A
, 9);
437 if (p
!= u2
.buf
+ off
) abort ();
440 p
= memset (u2
.buf
+ off
, 'B', 9);
441 if (p
!= u2
.buf
+ off
) abort ();
446 for (off
= 0; off
< MAX_OFFSET
; off
++)
450 p
= memset (u2
.buf
+ off
, '\0', 10);
451 if (p
!= u2
.buf
+ off
) abort ();
452 check (off
, 10, '\0');
454 p
= memset (u2
.buf
+ off
, A
, 10);
455 if (p
!= u2
.buf
+ off
) abort ();
456 check (off
, 10, 'A');
458 p
= memset (u2
.buf
+ off
, 'B', 10);
459 if (p
!= u2
.buf
+ off
) abort ();
460 check (off
, 10, 'B');
464 for (off
= 0; off
< MAX_OFFSET
; off
++)
468 p
= memset (u2
.buf
+ off
, '\0', 11);
469 if (p
!= u2
.buf
+ off
) abort ();
470 check (off
, 11, '\0');
472 p
= memset (u2
.buf
+ off
, A
, 11);
473 if (p
!= u2
.buf
+ off
) abort ();
474 check (off
, 11, 'A');
476 p
= memset (u2
.buf
+ off
, 'B', 11);
477 if (p
!= u2
.buf
+ off
) abort ();
478 check (off
, 11, 'B');
482 for (off
= 0; off
< MAX_OFFSET
; off
++)
486 p
= memset (u2
.buf
+ off
, '\0', 12);
487 if (p
!= u2
.buf
+ off
) abort ();
488 check (off
, 12, '\0');
490 p
= memset (u2
.buf
+ off
, A
, 12);
491 if (p
!= u2
.buf
+ off
) abort ();
492 check (off
, 12, 'A');
494 p
= memset (u2
.buf
+ off
, 'B', 12);
495 if (p
!= u2
.buf
+ off
) abort ();
496 check (off
, 12, 'B');
500 for (off
= 0; off
< MAX_OFFSET
; off
++)
504 p
= memset (u2
.buf
+ off
, '\0', 13);
505 if (p
!= u2
.buf
+ off
) abort ();
506 check (off
, 13, '\0');
508 p
= memset (u2
.buf
+ off
, A
, 13);
509 if (p
!= u2
.buf
+ off
) abort ();
510 check (off
, 13, 'A');
512 p
= memset (u2
.buf
+ off
, 'B', 13);
513 if (p
!= u2
.buf
+ off
) abort ();
514 check (off
, 13, 'B');
518 for (off
= 0; off
< MAX_OFFSET
; off
++)
522 p
= memset (u2
.buf
+ off
, '\0', 14);
523 if (p
!= u2
.buf
+ off
) abort ();
524 check (off
, 14, '\0');
526 p
= memset (u2
.buf
+ off
, A
, 14);
527 if (p
!= u2
.buf
+ off
) abort ();
528 check (off
, 14, 'A');
530 p
= memset (u2
.buf
+ off
, 'B', 14);
531 if (p
!= u2
.buf
+ off
) abort ();
532 check (off
, 14, 'B');
536 for (off
= 0; off
< MAX_OFFSET
; off
++)
540 p
= memset (u2
.buf
+ off
, '\0', 15);
541 if (p
!= u2
.buf
+ off
) abort ();
542 check (off
, 15, '\0');
544 p
= memset (u2
.buf
+ off
, A
, 15);
545 if (p
!= u2
.buf
+ off
) abort ();
546 check (off
, 15, 'A');
548 p
= memset (u2
.buf
+ off
, 'B', 15);
549 if (p
!= u2
.buf
+ off
) abort ();
550 check (off
, 15, 'B');
555 __attribute__((noinline
))
562 for (len
= 0; len
< MAX_COPY2
; len
++)
566 p
= memset (u2
.buf
, '\0', len
);
567 if (p
!= u2
.buf
) abort ();
568 check (0, len
, '\0');
570 p
= memset (u2
.buf
, A
, len
);
571 if (p
!= u2
.buf
) abort ();
574 p
= memset (u2
.buf
, 'B', len
);
575 if (p
!= u2
.buf
) abort ();
580 for (len
= 0; len
< MAX_COPY2
; len
++)
584 p
= memset (u2
.buf
+1, '\0', len
);
585 if (p
!= u2
.buf
+1) abort ();
586 check (1, len
, '\0');
588 p
= memset (u2
.buf
+1, A
, len
);
589 if (p
!= u2
.buf
+1) abort ();
592 p
= memset (u2
.buf
+1, 'B', len
);
593 if (p
!= u2
.buf
+1) abort ();
598 for (len
= 0; len
< MAX_COPY2
; len
++)
602 p
= memset (u2
.buf
+2, '\0', len
);
603 if (p
!= u2
.buf
+2) abort ();
604 check (2, len
, '\0');
606 p
= memset (u2
.buf
+2, A
, len
);
607 if (p
!= u2
.buf
+2) abort ();
610 p
= memset (u2
.buf
+2, 'B', len
);
611 if (p
!= u2
.buf
+2) abort ();
616 for (len
= 0; len
< MAX_COPY2
; len
++)
620 p
= memset (u2
.buf
+3, '\0', len
);
621 if (p
!= u2
.buf
+3) abort ();
622 check (3, len
, '\0');
624 p
= memset (u2
.buf
+3, A
, len
);
625 if (p
!= u2
.buf
+3) abort ();
628 p
= memset (u2
.buf
+3, 'B', len
);
629 if (p
!= u2
.buf
+3) abort ();
634 for (len
= 0; len
< MAX_COPY2
; len
++)
638 p
= memset (u2
.buf
+4, '\0', len
);
639 if (p
!= u2
.buf
+4) abort ();
640 check (4, len
, '\0');
642 p
= memset (u2
.buf
+4, A
, len
);
643 if (p
!= u2
.buf
+4) abort ();
646 p
= memset (u2
.buf
+4, 'B', len
);
647 if (p
!= u2
.buf
+4) abort ();
652 for (len
= 0; len
< MAX_COPY2
; len
++)
656 p
= memset (u2
.buf
+5, '\0', len
);
657 if (p
!= u2
.buf
+5) abort ();
658 check (5, len
, '\0');
660 p
= memset (u2
.buf
+5, A
, len
);
661 if (p
!= u2
.buf
+5) abort ();
664 p
= memset (u2
.buf
+5, 'B', len
);
665 if (p
!= u2
.buf
+5) abort ();
670 for (len
= 0; len
< MAX_COPY2
; len
++)
674 p
= memset (u2
.buf
+6, '\0', len
);
675 if (p
!= u2
.buf
+6) abort ();
676 check (6, len
, '\0');
678 p
= memset (u2
.buf
+6, A
, len
);
679 if (p
!= u2
.buf
+6) abort ();
682 p
= memset (u2
.buf
+6, 'B', len
);
683 if (p
!= u2
.buf
+6) abort ();
688 for (len
= 0; len
< MAX_COPY2
; len
++)
692 p
= memset (u2
.buf
+7, '\0', len
);
693 if (p
!= u2
.buf
+7) abort ();
694 check (7, len
, '\0');
696 p
= memset (u2
.buf
+7, A
, len
);
697 if (p
!= u2
.buf
+7) abort ();
700 p
= memset (u2
.buf
+7, 'B', len
);
701 if (p
!= u2
.buf
+7) abort ();
710 /* Object size checking is only intended for -O[s123]. */
713 __asm ("" : "=r" (l1
) : "0" (l1
));