1 /* Copyright (C) 2004, 2005 Free Software Foundation.
3 Ensure builtin __strncpy_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 *strncpy (char *, const char *, size_t);
10 extern int memcmp (const void *, const void *, size_t);
11 extern int strcmp (const char *, const char *);
12 extern int strncmp (const char *, const char *, size_t);
13 extern void *memset (void *, int, size_t);
17 const char s1
[] = "123";
26 __attribute__((noinline
))
29 const char *const src
= "hello world";
33 strncpy_disallowed
= 1;
36 memset (dst
, 0, sizeof (dst
));
37 if (strncpy (dst
, src
, 4) != dst
|| strncmp (dst
, src
, 4))
40 memset (dst
, 0, sizeof (dst
));
41 if (strncpy (dst
+16, src
, 4) != dst
+16 || strncmp (dst
+16, src
, 4))
44 memset (dst
, 0, sizeof (dst
));
45 if (strncpy (dst
+32, src
+5, 4) != dst
+32 || strncmp (dst
+32, src
+5, 4))
48 memset (dst
, 0, sizeof (dst
));
50 if (strncpy (++dst2
, src
+5, 4) != dst
+1 || strncmp (dst2
, src
+5, 4)
54 memset (dst
, 0, sizeof (dst
));
55 if (strncpy (dst
, src
, 0) != dst
|| strcmp (dst
, ""))
58 memset (dst
, 0, sizeof (dst
));
59 dst2
= dst
; src2
= src
;
60 if (strncpy (++dst2
, ++src2
, 0) != dst
+1 || strcmp (dst2
, "")
61 || dst2
!= dst
+1 || src2
!= src
+1)
64 memset (dst
, 0, sizeof (dst
));
65 dst2
= dst
; src2
= src
;
66 if (strncpy (++dst2
+5, ++src2
+5, 0) != dst
+6 || strcmp (dst2
+5, "")
67 || dst2
!= dst
+1 || src2
!= src
+1)
70 memset (dst
, 0, sizeof (dst
));
71 if (strncpy (dst
, src
, 12) != dst
|| strcmp (dst
, src
))
74 /* Test at least one instance of the __builtin_ style. We do this
75 to ensure that it works and that the prototype is correct. */
76 memset (dst
, 0, sizeof (dst
));
77 if (__builtin_strncpy (dst
, src
, 4) != dst
|| strncmp (dst
, src
, 4))
80 memset (dst
, 0, sizeof (dst
));
81 if (strncpy (dst
, i
++ ? "xfoo" + 1 : "bar", 4) != dst
82 || strcmp (dst
, "bar")
88 strncpy_disallowed
= 0;
92 __attribute__((noinline
))
96 /* No runtime checking should be done here, both destination
97 and length are unknown. */
98 strncpy (s4
, "abcd", l1
+ 1);
103 /* Test whether compile time checking is done where it should
104 and so is runtime object size checking. */
106 __attribute__((noinline
))
109 struct A
{ char buf1
[10]; char buf2
[10]; } a
;
110 char *r
= l1
== 1 ? &a
.buf1
[5] : &a
.buf2
[4];
116 /* The following calls should do runtime checking
117 - source length is not known, but destination is. */
119 strncpy (a
.buf1
+ 2, s3
+ 3, l1
);
120 strncpy (r
, s3
+ 2, l1
+ 2);
121 r
= l1
== 1 ? __builtin_alloca (4) : &a
.buf2
[7];
122 strncpy (r
, s2
+ 2, l1
+ 2);
123 strncpy (r
+ 2, s3
+ 3, l1
);
125 for (i
= 0; i
< 4; ++i
)
131 else if (i
== l1
+ 1)
133 else if (i
== l1
+ 2)
136 strncpy (r
, s2
+ 4, l1
);
140 /* Following have known destination and known length,
141 so if optimizing certainly shouldn't result in the checking
144 strncpy (a
.buf1
+ 2, "", 3);
145 strncpy (a
.buf1
+ 2, "", 0);
148 r
= l1
== 1 ? __builtin_alloca (4) : &a
.buf2
[7];
149 strncpy (r
, s1
+ 1, 3);
150 strncpy (r
, s1
+ 1, 2);
154 for (i
= 0; i
< 4; ++i
)
157 r
= &a
.buf1
[1], l
= "e", l2
= 2;
159 r
= &a
.buf2
[7], l
= "gh", l2
= 3;
160 else if (i
== l1
+ 1)
161 r
= &buf3
[5], l
= "jkl", l2
= 4;
162 else if (i
== l1
+ 2)
163 r
= &a
.buf1
[9], l
= "", l2
= 1;
166 /* Here, strlen (l) + 1 is known to be at most 4 and
167 __builtin_object_size (&buf3[16], 0) is 4, so this doesn't need
169 strncpy (&buf3
[16], l
, l2
);
170 strncpy (&buf3
[15], "abc", l2
);
171 strncpy (&buf3
[10], "fghij", l2
);
177 /* Test whether runtime and/or compile time checking catches
180 __attribute__((noinline
))
183 struct A
{ char buf1
[10]; char buf2
[10]; } a
;
186 chk_fail_allowed
= 1;
187 /* Runtime checks. */
188 if (__builtin_setjmp (chk_fail_buf
) == 0)
190 strncpy (&a
.buf2
[9], s2
+ 4, l1
+ 1);
193 if (__builtin_setjmp (chk_fail_buf
) == 0)
195 strncpy (&a
.buf2
[7], s3
, l1
+ 4);
198 /* This should be detectable at compile time already. */
199 if (__builtin_setjmp (chk_fail_buf
) == 0)
201 strncpy (&buf3
[19], "abc", 2);
204 if (__builtin_setjmp (chk_fail_buf
) == 0)
206 strncpy (&buf3
[18], "", 3);
209 chk_fail_allowed
= 0;
216 /* Object size checking is only intended for -O[s123]. */
219 __asm ("" : "=r" (s2
) : "0" (s2
));
220 __asm ("" : "=r" (s3
) : "0" (s3
));
221 __asm ("" : "=r" (l1
) : "0" (l1
));