1 /* Copyright (C) 2004, 2005 Free Software Foundation.
3 Ensure builtin __vsprintf_chk performs correctly. */
7 extern void abort (void);
8 typedef __SIZE_TYPE__
size_t;
9 extern size_t strlen(const char *);
10 extern void *memcpy (void *, const void *, size_t);
11 extern char *strcpy (char *, const char *);
12 extern int memcmp (const void *, const void *, size_t);
13 extern void *memset (void *, int, size_t);
14 extern int vsprintf (char *, const char *, va_list);
18 const char s1
[] = "123";
24 static char buffer
[32];
28 __attribute__((noinline
))
29 test1_sub (int i
, ...)
37 vsprintf (buffer
, "foo", ap
);
40 ret
= vsprintf (buffer
, "foo", ap
);
43 vsprintf (buffer
, "%s", ap
);
46 ret
= vsprintf (buffer
, "%s", ap
);
49 vsprintf (buffer
, "%d - %c", ap
);
52 vsprintf (s4
, "%d - %c", ap
);
60 __attribute__((noinline
))
64 vsprintf_disallowed
= 1;
66 memset (buffer
, 'A', 32);
68 if (memcmp (buffer
, "foo", 4) || buffer
[4] != 'A')
71 memset (buffer
, 'A', 32);
72 if (test1_sub (1) != 3)
74 if (memcmp (buffer
, "foo", 4) || buffer
[4] != 'A')
79 vsprintf_disallowed
= 0;
81 memset (buffer
, 'A', 32);
83 if (memcmp (buffer
, "bar", 4) || buffer
[4] != 'A')
86 memset (buffer
, 'A', 32);
87 if (test1_sub (3, "bar") != 3)
89 if (memcmp (buffer
, "bar", 4) || buffer
[4] != 'A')
92 memset (buffer
, 'A', 32);
94 if (memcmp (buffer
, "barf", 5) || buffer
[5] != 'A')
97 memset (buffer
, 'A', 32);
98 test1_sub (4, (int) l1
+ 27, *ptr
);
99 if (memcmp (buffer
, "28 - b\0AAAAA", 12))
106 test1_sub (5, (int) l1
- 17, ptr
[1]);
107 if (memcmp (s4
, "-16 - a", 8))
114 __attribute__((noinline
))
115 test2_sub (int i
, ...)
118 struct A
{ char buf1
[10]; char buf2
[10]; } a
;
119 char *r
= l1
== 1 ? &a
.buf1
[5] : &a
.buf2
[4];
124 /* The following calls should do runtime checking
125 - source length is not known, but destination is. */
129 vsprintf (a
.buf1
+ 2, "%s", ap
);
132 vsprintf (r
, "%s%c", ap
);
135 r
= l1
== 1 ? __builtin_alloca (4) : &a
.buf2
[7];
136 vsprintf (r
, "%c %s", ap
);
139 r
= l1
== 1 ? __builtin_alloca (4) : &a
.buf2
[7];
140 vsprintf (r
+ 2, s3
+ 3, ap
);
145 for (j
= 0; j
< 4; ++j
)
151 else if (j
== l1
+ 1)
153 else if (j
== l1
+ 2)
157 vsprintf (r
, s2
+ 4, ap
);
159 vsprintf (r
, "a", ap
);
162 r
= l1
== 1 ? __builtin_alloca (4) : &a
.buf2
[7];
163 vsprintf (r
, "%s", ap
);
166 vsprintf (a
.buf1
+ 2, "", ap
);
169 vsprintf (s4
, "%s %d", ap
);
175 /* Test whether compile time checking is done where it should
176 and so is runtime object size checking. */
178 __attribute__((noinline
))
181 /* The following calls should do runtime checking
182 - source length is not known, but destination is. */
184 test2_sub (0, s3
+ 3);
185 test2_sub (1, s3
+ 3, s3
[3]);
186 test2_sub (2, s2
[2], s2
+ 4);
189 test2_sub (5, s1
+ 1);
193 /* Following have known destination and known source length,
194 so if optimizing certainly shouldn't result in the checking
197 vsprintf_disallowed
= 1;
200 vsprintf_disallowed
= 0;
201 /* Unknown destination and source, no checking. */
202 test2_sub (8, s3
, 0);
208 __attribute__((noinline
))
209 test3_sub (int i
, ...)
212 struct A
{ char buf1
[10]; char buf2
[10]; } a
;
216 /* The following calls should do runtime checking
217 - source length is not known, but destination is. */
221 vsprintf (&a
.buf2
[9], "%c%s", ap
);
224 vsprintf (&a
.buf2
[7], "%s%c", ap
);
227 vsprintf (&a
.buf2
[7], "%d", ap
);
230 vsprintf (&buf3
[17], "%s", ap
);
233 vsprintf (&buf3
[19], "a", ap
);
239 /* Test whether runtime and/or compile time checking catches
242 __attribute__((noinline
))
245 chk_fail_allowed
= 1;
246 /* Runtime checks. */
247 if (__builtin_setjmp (chk_fail_buf
) == 0)
249 test3_sub (0, s2
[3], s2
+ 4);
252 if (__builtin_setjmp (chk_fail_buf
) == 0)
254 test3_sub (1, s3
+ strlen (s3
) - 2, *s3
);
257 if (__builtin_setjmp (chk_fail_buf
) == 0)
259 test3_sub (2, (int) l1
+ 9999);
262 if (__builtin_setjmp (chk_fail_buf
) == 0)
264 test3_sub (3, "abc");
267 /* This should be detectable at compile time already. */
268 if (__builtin_setjmp (chk_fail_buf
) == 0)
273 chk_fail_allowed
= 0;
280 /* Object size checking is only intended for -O[s123]. */
283 __asm ("" : "=r" (s2
) : "0" (s2
));
284 __asm ("" : "=r" (s3
) : "0" (s3
));
285 __asm ("" : "=r" (l1
) : "0" (l1
));