]>
git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/testsuite/gcc.c-torture/execute/builtins/strcpy-chk.c
1 /* Copyright (C) 2004, 2005 Free Software Foundation.
3 Ensure builtin __strcpy_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);
14 const char s1
[] = "123";
22 __attribute__((noinline
))
26 #ifndef __OPTIMIZE_SIZE__
27 strcpy_disallowed
= 1;
29 strcpy_disallowed
= 0;
32 if (strcpy (p
, "abcde") != p
|| memcmp (p
, "abcde", 6))
34 if (strcpy (p
+ 16, "vwxyz" + 1) != p
+ 16 || memcmp (p
+ 16, "wxyz", 5))
36 if (strcpy (p
+ 1, "") != p
+ 1 || memcmp (p
, "a\0cde", 6))
38 if (strcpy (p
+ 3, "fghij") != p
+ 3 || memcmp (p
, "a\0cfghij", 9))
41 /* Test at least one instance of the __builtin_ style. We do this
42 to ensure that it works and that the prototype is correct. */
43 if (__builtin_strcpy (p
, "abcde") != p
|| memcmp (p
, "abcde", 6))
46 strcpy_disallowed
= 0;
52 #define MAX_OFFSET (sizeof (long long))
56 #define MAX_COPY (10 * sizeof (long long))
60 #define MAX_EXTRA (sizeof (long long))
63 #define MAX_LENGTH (MAX_OFFSET + MAX_COPY + 1 + MAX_EXTRA)
65 /* Use a sequence length that is not divisible by two, to make it more
66 likely to detect when words are mixed up. */
67 #define SEQUENCE_LENGTH 31
76 __attribute__((noinline
))
79 int off1
, off2
, len
, i
;
82 for (off1
= 0; off1
< MAX_OFFSET
; off1
++)
83 for (off2
= 0; off2
< MAX_OFFSET
; off2
++)
84 for (len
= 1; len
< MAX_COPY
; len
++)
86 for (i
= 0, c
= 'A'; i
< MAX_LENGTH
; i
++, c
++)
89 if (c
>= 'A' + SEQUENCE_LENGTH
)
93 u2
.buf
[off2
+ len
] = '\0';
95 p
= strcpy (u1
.buf
+ off1
, u2
.buf
+ off2
);
96 if (p
!= u1
.buf
+ off1
)
100 for (i
= 0; i
< off1
; i
++, q
++)
104 for (i
= 0, c
= 'A' + off2
; i
< len
; i
++, q
++, c
++)
106 if (c
>= 'A' + SEQUENCE_LENGTH
)
114 for (i
= 0; i
< MAX_EXTRA
; i
++, q
++)
120 /* Test whether compile time checking is done where it should
121 and so is runtime object size checking. */
123 __attribute__((noinline
))
126 struct A
{ char buf1
[10]; char buf2
[10]; } a
;
127 char *r
= l1
== 1 ? &a
.buf1
[5] : &a
.buf2
[4];
132 /* The following calls should do runtime checking
133 - source length is not known, but destination is. */
135 strcpy (a
.buf1
+ 2, s3
+ 3);
137 r
= l1
== 1 ? __builtin_alloca (4) : &a
.buf2
[7];
139 strcpy (r
+ 2, s3
+ 3);
141 for (i
= 0; i
< 4; ++i
)
147 else if (i
== l1
+ 1)
149 else if (i
== l1
+ 2)
156 /* Following have known destination and known source length,
157 so if optimizing certainly shouldn't result in the checking
160 strcpy (a
.buf1
+ 2, "");
162 r
= l1
== 1 ? __builtin_alloca (4) : &a
.buf2
[7];
166 for (i
= 0; i
< 4; ++i
)
169 r
= &a
.buf1
[1], l
= "e";
171 r
= &a
.buf2
[7], l
= "gh";
172 else if (i
== l1
+ 1)
173 r
= &buf3
[5], l
= "jkl";
174 else if (i
== l1
+ 2)
175 r
= &a
.buf1
[9], l
= "";
178 /* Here, strlen (l) + 1 is known to be at most 4 and
179 __builtin_object_size (&buf3[16], 0) is 4, so this doesn't need
181 strcpy (&buf3
[16], l
);
182 /* Unknown destination and source, no checking. */
189 /* Test whether runtime and/or compile time checking catches
192 __attribute__((noinline
))
195 struct A
{ char buf1
[10]; char buf2
[10]; } a
;
198 chk_fail_allowed
= 1;
199 /* Runtime checks. */
200 if (__builtin_setjmp (chk_fail_buf
) == 0)
202 strcpy (&a
.buf2
[9], s2
+ 3);
205 if (__builtin_setjmp (chk_fail_buf
) == 0)
207 strcpy (&a
.buf2
[7], s3
+ strlen (s3
) - 3);
210 /* This should be detectable at compile time already. */
211 if (__builtin_setjmp (chk_fail_buf
) == 0)
213 strcpy (&buf3
[19], "a");
216 chk_fail_allowed
= 0;
223 /* Object size checking is only intended for -O[s123]. */
226 __asm ("" : "=r" (s2
) : "0" (s2
));
227 __asm ("" : "=r" (s3
) : "0" (s3
));
228 __asm ("" : "=r" (l1
) : "0" (l1
));