1 /* Copyright (C) 2004, 2005 Free Software Foundation.
3 Ensure builtin __sprintf_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 char *strcpy (char *, const char *);
10 extern int memcmp (const void *, const void *, size_t);
11 extern void *memset (void *, int, size_t);
12 extern int sprintf (char *, const char *, ...);
16 LOCAL
const char s1
[] = "123";
22 static char buffer
[32];
26 __attribute__((noinline
))
30 sprintf_disallowed
= 1;
32 memset (buffer
, 'A', 32);
33 sprintf (buffer
, "foo");
34 if (memcmp (buffer
, "foo", 4) || buffer
[4] != 'A')
37 memset (buffer
, 'A', 32);
38 if (sprintf (buffer
, "foo") != 3)
40 if (memcmp (buffer
, "foo", 4) || buffer
[4] != 'A')
43 memset (buffer
, 'A', 32);
44 sprintf (buffer
, "%s", "bar");
45 if (memcmp (buffer
, "bar", 4) || buffer
[4] != 'A')
48 memset (buffer
, 'A', 32);
49 if (sprintf (buffer
, "%s", "bar") != 3)
51 if (memcmp (buffer
, "bar", 4) || buffer
[4] != 'A')
56 sprintf_disallowed
= 0;
58 memset (buffer
, 'A', 32);
59 sprintf (buffer
, "%s", ptr
);
60 if (memcmp (buffer
, "barf", 5) || buffer
[5] != 'A')
63 memset (buffer
, 'A', 32);
64 sprintf (buffer
, "%d - %c", (int) l1
+ 27, *ptr
);
65 if (memcmp (buffer
, "28 - b\0AAAAA", 12))
72 sprintf (s4
, "%d - %c", (int) l1
- 17, ptr
[1]);
73 if (memcmp (s4
, "-16 - a", 8))
79 /* Test whether compile time checking is done where it should
80 and so is runtime object size checking. */
82 __attribute__((noinline
))
85 struct A
{ char buf1
[10]; char buf2
[10]; } a
;
86 char *r
= l1
== 1 ? &a
.buf1
[5] : &a
.buf2
[4];
90 /* The following calls should do runtime checking
91 - source length is not known, but destination is. */
93 sprintf (a
.buf1
+ 2, "%s", s3
+ 3);
94 sprintf (r
, "%s%c", s3
+ 3, s3
[3]);
95 r
= l1
== 1 ? __builtin_alloca (4) : &a
.buf2
[7];
96 sprintf (r
, "%c %s", s2
[2], s2
+ 4);
97 sprintf (r
+ 2, s3
+ 3);
99 for (i
= 0; i
< 4; ++i
)
105 else if (i
== l1
+ 1)
107 else if (i
== l1
+ 2)
114 /* Following have known destination and known source length,
115 so if optimizing certainly shouldn't result in the checking
118 sprintf_disallowed
= 1;
119 sprintf (a
.buf1
+ 2, "");
121 r
= l1
== 1 ? __builtin_alloca (4) : &a
.buf2
[7];
122 sprintf (r
, "%s", s1
+ 1);
124 for (i
= 0; i
< 4; ++i
)
130 else if (i
== l1
+ 1)
132 else if (i
== l1
+ 2)
135 sprintf (r
, "%s", "");
136 sprintf_disallowed
= 0;
137 /* Unknown destination and source, no checking. */
138 sprintf (s4
, "%s %d", s3
, 0);
143 /* Test whether runtime and/or compile time checking catches
146 __attribute__((noinline
))
149 struct A
{ char buf1
[10]; char buf2
[10]; } a
;
152 chk_fail_allowed
= 1;
153 /* Runtime checks. */
154 if (__builtin_setjmp (chk_fail_buf
) == 0)
156 sprintf (&a
.buf2
[9], "%c%s", s2
[3], s2
+ 4);
159 if (__builtin_setjmp (chk_fail_buf
) == 0)
161 sprintf (&a
.buf2
[7], "%s%c", s3
+ strlen (s3
) - 2, *s3
);
164 if (__builtin_setjmp (chk_fail_buf
) == 0)
166 sprintf (&a
.buf2
[7], "%d", (int) l1
+ 9999);
169 /* This should be detectable at compile time already. */
170 if (__builtin_setjmp (chk_fail_buf
) == 0)
172 sprintf (&buf3
[19], "a");
175 if (__builtin_setjmp (chk_fail_buf
) == 0)
177 sprintf (&buf3
[17], "%s", "abc");
180 chk_fail_allowed
= 0;
187 /* Object size checking is only intended for -O[s123]. */
190 __asm ("" : "=r" (s2
) : "0" (s2
));
191 __asm ("" : "=r" (s3
) : "0" (s3
));
192 __asm ("" : "=r" (l1
) : "0" (l1
));