Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / gcc / testsuite / gcc.c-torture / execute / builtins / vsprintf-chk.c
blob5c150901800ef9da78dbf86d001cc0d9667360d4
1 /* Copyright (C) 2004, 2005 Free Software Foundation.
3 Ensure builtin __vsprintf_chk performs correctly. */
5 #include <stdarg.h>
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);
16 #include "chk.h"
18 const char s1[] = "123";
19 char p[32] = "";
20 char *s2 = "defg";
21 char *s3 = "FGH";
22 char *s4;
23 size_t l1 = 1;
24 static char buffer[32];
25 char *ptr = "barf";
27 int
28 __attribute__((noinline))
29 test1_sub (int i, ...)
31 int ret = 0;
32 va_list ap;
33 va_start (ap, i);
34 switch (i)
36 case 0:
37 vsprintf (buffer, "foo", ap);
38 break;
39 case 1:
40 ret = vsprintf (buffer, "foo", ap);
41 break;
42 case 2:
43 vsprintf (buffer, "%s", ap);
44 break;
45 case 3:
46 ret = vsprintf (buffer, "%s", ap);
47 break;
48 case 4:
49 vsprintf (buffer, "%d - %c", ap);
50 break;
51 case 5:
52 vsprintf (s4, "%d - %c", ap);
53 break;
55 va_end (ap);
56 return ret;
59 void
60 __attribute__((noinline))
61 test1 (void)
63 chk_calls = 0;
64 vsprintf_disallowed = 1;
66 memset (buffer, 'A', 32);
67 test1_sub (0);
68 if (memcmp (buffer, "foo", 4) || buffer[4] != 'A')
69 abort ();
71 memset (buffer, 'A', 32);
72 if (test1_sub (1) != 3)
73 abort ();
74 if (memcmp (buffer, "foo", 4) || buffer[4] != 'A')
75 abort ();
77 if (chk_calls)
78 abort ();
79 vsprintf_disallowed = 0;
81 memset (buffer, 'A', 32);
82 test1_sub (2, "bar");
83 if (memcmp (buffer, "bar", 4) || buffer[4] != 'A')
84 abort ();
86 memset (buffer, 'A', 32);
87 if (test1_sub (3, "bar") != 3)
88 abort ();
89 if (memcmp (buffer, "bar", 4) || buffer[4] != 'A')
90 abort ();
92 memset (buffer, 'A', 32);
93 test1_sub (2, ptr);
94 if (memcmp (buffer, "barf", 5) || buffer[5] != 'A')
95 abort ();
97 memset (buffer, 'A', 32);
98 test1_sub (4, (int) l1 + 27, *ptr);
99 if (memcmp (buffer, "28 - b\0AAAAA", 12))
100 abort ();
102 if (chk_calls != 4)
103 abort ();
104 chk_calls = 0;
106 test1_sub (5, (int) l1 - 17, ptr[1]);
107 if (memcmp (s4, "-16 - a", 8))
108 abort ();
109 if (chk_calls)
110 abort ();
113 void
114 __attribute__((noinline))
115 test2_sub (int i, ...)
117 va_list ap;
118 struct A { char buf1[10]; char buf2[10]; } a;
119 char *r = l1 == 1 ? &a.buf1[5] : &a.buf2[4];
120 char buf3[20];
121 int j;
123 va_start (ap, i);
124 /* The following calls should do runtime checking
125 - source length is not known, but destination is. */
126 switch (i)
128 case 0:
129 vsprintf (a.buf1 + 2, "%s", ap);
130 break;
131 case 1:
132 vsprintf (r, "%s%c", ap);
133 break;
134 case 2:
135 r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7];
136 vsprintf (r, "%c %s", ap);
137 break;
138 case 3:
139 r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7];
140 vsprintf (r + 2, s3 + 3, ap);
141 break;
142 case 4:
143 case 7:
144 r = buf3;
145 for (j = 0; j < 4; ++j)
147 if (j == l1 - 1)
148 r = &a.buf1[1];
149 else if (j == l1)
150 r = &a.buf2[7];
151 else if (j == l1 + 1)
152 r = &buf3[5];
153 else if (j == l1 + 2)
154 r = &a.buf1[9];
156 if (i == 4)
157 vsprintf (r, s2 + 4, ap);
158 else
159 vsprintf (r, "a", ap);
160 break;
161 case 5:
162 r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7];
163 vsprintf (r, "%s", ap);
164 break;
165 case 6:
166 vsprintf (a.buf1 + 2, "", ap);
167 break;
168 case 8:
169 vsprintf (s4, "%s %d", ap);
170 break;
172 va_end (ap);
175 /* Test whether compile time checking is done where it should
176 and so is runtime object size checking. */
177 void
178 __attribute__((noinline))
179 test2 (void)
181 /* The following calls should do runtime checking
182 - source length is not known, but destination is. */
183 chk_calls = 0;
184 test2_sub (0, s3 + 3);
185 test2_sub (1, s3 + 3, s3[3]);
186 test2_sub (2, s2[2], s2 + 4);
187 test2_sub (3);
188 test2_sub (4);
189 test2_sub (5, s1 + 1);
190 if (chk_calls != 6)
191 abort ();
193 /* Following have known destination and known source length,
194 so if optimizing certainly shouldn't result in the checking
195 variants. */
196 chk_calls = 0;
197 vsprintf_disallowed = 1;
198 test2_sub (6);
199 test2_sub (7);
200 vsprintf_disallowed = 0;
201 /* Unknown destination and source, no checking. */
202 test2_sub (8, s3, 0);
203 if (chk_calls)
204 abort ();
207 void
208 __attribute__((noinline))
209 test3_sub (int i, ...)
211 va_list ap;
212 struct A { char buf1[10]; char buf2[10]; } a;
213 char buf3[20];
215 va_start (ap, i);
216 /* The following calls should do runtime checking
217 - source length is not known, but destination is. */
218 switch (i)
220 case 0:
221 vsprintf (&a.buf2[9], "%c%s", ap);
222 break;
223 case 1:
224 vsprintf (&a.buf2[7], "%s%c", ap);
225 break;
226 case 2:
227 vsprintf (&a.buf2[7], "%d", ap);
228 break;
229 case 3:
230 vsprintf (&buf3[17], "%s", ap);
231 break;
232 case 4:
233 vsprintf (&buf3[19], "a", ap);
234 break;
236 va_end (ap);
239 /* Test whether runtime and/or compile time checking catches
240 buffer overflows. */
241 void
242 __attribute__((noinline))
243 test3 (void)
245 chk_fail_allowed = 1;
246 /* Runtime checks. */
247 if (__builtin_setjmp (chk_fail_buf) == 0)
249 test3_sub (0, s2[3], s2 + 4);
250 abort ();
252 if (__builtin_setjmp (chk_fail_buf) == 0)
254 test3_sub (1, s3 + strlen (s3) - 2, *s3);
255 abort ();
257 if (__builtin_setjmp (chk_fail_buf) == 0)
259 test3_sub (2, (int) l1 + 9999);
260 abort ();
262 if (__builtin_setjmp (chk_fail_buf) == 0)
264 test3_sub (3, "abc");
265 abort ();
267 /* This should be detectable at compile time already. */
268 if (__builtin_setjmp (chk_fail_buf) == 0)
270 test3_sub (4);
271 abort ();
273 chk_fail_allowed = 0;
276 void
277 main_test (void)
279 #ifndef __OPTIMIZE__
280 /* Object size checking is only intended for -O[s123]. */
281 return;
282 #endif
283 __asm ("" : "=r" (s2) : "0" (s2));
284 __asm ("" : "=r" (s3) : "0" (s3));
285 __asm ("" : "=r" (l1) : "0" (l1));
286 s4 = p;
287 test1 ();
288 test2 ();
289 test3 ();