1 /* Copyright (C) 2004, 2005 Free Software Foundation.
3 Ensure builtin __stpcpy_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 *stpcpy (char *, const char *);
10 extern int memcmp (const void *, const void *, size_t);
14 LOCAL
const char s1
[] = "123";
22 __attribute__((noinline
))
27 #if defined __i386__ || defined __x86_64__
28 /* The functions below might not be optimized into direct stores on all
29 arches. It depends on how many instructions would be generated and
30 what limits the architecture chooses in STORE_BY_PIECES_P. */
31 stpcpy_disallowed
= 1;
33 if (stpcpy (p
, "abcde") != p
+ 5 || memcmp (p
, "abcde", 6))
35 if (stpcpy (p
+ 16, "vwxyz" + 1) != p
+ 16 + 4 || memcmp (p
+ 16, "wxyz", 5))
37 if (stpcpy (p
+ 1, "") != p
+ 1 + 0 || memcmp (p
, "a\0cde", 6))
39 if (stpcpy (p
+ 3, "fghij") != p
+ 3 + 5 || memcmp (p
, "a\0cfghij", 9))
42 if (stpcpy ((i
++, p
+ 20 + 1), "23") != (p
+ 20 + 1 + 2)
43 || i
!= 9 || memcmp (p
+ 19, "z\0""23\0", 5))
46 if (stpcpy (stpcpy (p
, "ABCD"), "EFG") != p
+ 7 || memcmp (p
, "ABCDEFG", 8))
49 /* Test at least one instance of the __builtin_ style. We do this
50 to ensure that it works and that the prototype is correct. */
51 if (__builtin_stpcpy (p
, "abcde") != p
+ 5 || memcmp (p
, "abcde", 6))
54 /* If return value of stpcpy is ignored, it should be optimized into
56 stpcpy_disallowed
= 1;
57 stpcpy (p
+ 1, "abcd");
58 stpcpy_disallowed
= 0;
59 if (memcmp (p
, "aabcd", 6))
66 strcpy_disallowed
= 1;
67 if (stpcpy (p
, s2
) != p
+ 4 || memcmp (p
, "defg\0", 6))
69 strcpy_disallowed
= 0;
70 stpcpy_disallowed
= 1;
72 stpcpy_disallowed
= 0;
73 if (memcmp (p
, "deFGH", 6))
80 #define MAX_OFFSET (sizeof (long long))
84 #define MAX_COPY (10 * sizeof (long long))
88 #define MAX_EXTRA (sizeof (long long))
91 #define MAX_LENGTH (MAX_OFFSET + MAX_COPY + 1 + MAX_EXTRA)
93 /* Use a sequence length that is not divisible by two, to make it more
94 likely to detect when words are mixed up. */
95 #define SEQUENCE_LENGTH 31
100 long double align_fp
;
106 __attribute__((noinline
))
109 int off1
, off2
, len
, i
;
112 for (off1
= 0; off1
< MAX_OFFSET
; off1
++)
113 for (off2
= 0; off2
< MAX_OFFSET
; off2
++)
114 for (len
= 1; len
< MAX_COPY
; len
++)
116 for (i
= 0, c
= 'A'; i
< MAX_LENGTH
; i
++, c
++)
119 if (c
>= 'A' + SEQUENCE_LENGTH
)
123 u2
.buf
[off2
+ len
] = '\0';
125 p
= stpcpy (u1
.buf
+ off1
, u2
.buf
+ off2
);
126 if (p
!= u1
.buf
+ off1
+ len
)
130 for (i
= 0; i
< off1
; i
++, q
++)
134 for (i
= 0, c
= 'A' + off2
; i
< len
; i
++, q
++, c
++)
136 if (c
>= 'A' + SEQUENCE_LENGTH
)
144 for (i
= 0; i
< MAX_EXTRA
; i
++, q
++)
150 /* Test whether compile time checking is done where it should
151 and so is runtime object size checking. */
153 __attribute__((noinline
))
156 struct A
{ char buf1
[10]; char buf2
[10]; } a
;
157 char *r
= l1
== 1 ? &a
.buf1
[5] : &a
.buf2
[4];
162 /* The following calls should do runtime checking
163 - source length is not known, but destination is. */
165 vx
= stpcpy (a
.buf1
+ 2, s3
+ 3);
166 vx
= stpcpy (r
, s3
+ 2);
167 r
= l1
== 1 ? __builtin_alloca (4) : &a
.buf2
[7];
168 vx
= stpcpy (r
, s2
+ 2);
169 vx
= stpcpy (r
+ 2, s3
+ 3);
171 for (i
= 0; i
< 4; ++i
)
177 else if (i
== l1
+ 1)
179 else if (i
== l1
+ 2)
182 vx
= stpcpy (r
, s2
+ 4);
186 /* Following have known destination and known source length,
187 so if optimizing certainly shouldn't result in the checking
190 vx
= stpcpy (a
.buf1
+ 2, "");
191 vx
= stpcpy (r
, "a");
192 r
= l1
== 1 ? __builtin_alloca (4) : &a
.buf2
[7];
193 vx
= stpcpy (r
, s1
+ 1);
196 for (i
= 0; i
< 4; ++i
)
199 r
= &a
.buf1
[1], l
= "e";
201 r
= &a
.buf2
[7], l
= "gh";
202 else if (i
== l1
+ 1)
203 r
= &buf3
[5], l
= "jkl";
204 else if (i
== l1
+ 2)
205 r
= &a
.buf1
[9], l
= "";
208 /* Here, strlen (l) + 1 is known to be at most 4 and
209 __builtin_object_size (&buf3[16], 0) is 4, so this doesn't need
211 vx
= stpcpy (&buf3
[16], l
);
212 /* Unknown destination and source, no checking. */
213 vx
= stpcpy (s4
, s3
);
220 /* Test whether runtime and/or compile time checking catches
223 __attribute__((noinline
))
226 struct A
{ char buf1
[10]; char buf2
[10]; } a
;
229 chk_fail_allowed
= 1;
230 /* Runtime checks. */
231 if (__builtin_setjmp (chk_fail_buf
) == 0)
233 vx
= stpcpy (&a
.buf2
[9], s2
+ 3);
236 if (__builtin_setjmp (chk_fail_buf
) == 0)
238 vx
= stpcpy (&a
.buf2
[7], s3
+ strlen (s3
) - 3);
241 /* This should be detectable at compile time already. */
242 if (__builtin_setjmp (chk_fail_buf
) == 0)
244 vx
= stpcpy (&buf3
[19], "a");
247 chk_fail_allowed
= 0;
254 /* Object size checking is only intended for -O[s123]. */
257 __asm ("" : "=r" (s2
) : "0" (s2
));
258 __asm ("" : "=r" (s3
) : "0" (s3
));
259 __asm ("" : "=r" (l1
) : "0" (l1
));