blob: fee3bdf37f1fe9069090d04da9347728c4175be7 [file] [log] [blame]
xf.libdd93d52023-05-12 07:10:14 -07001/* Test memset functions.
2 Copyright (C) 1999-2016 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Written by Jakub Jelinek <jakub@redhat.com>, 1999.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>. */
19
20#define TEST_MAIN
21#ifdef TEST_BZERO
22# define TEST_NAME "bzero"
23#else
24# ifndef WIDE
25# define TEST_NAME "memset"
26# else
27# define TEST_NAME "wmemset"
28# endif /* WIDE */
29#endif /* !TEST_BZERO */
30#define MIN_PAGE_SIZE 131072
31#include "test-string.h"
32
33#ifndef WIDE
34# define MEMSET memset
35# define CHAR char
36# define UCHAR unsigned char
37# define SIMPLE_MEMSET simple_memset
38# define MEMCMP memcmp
39# define BIG_CHAR CHAR_MAX
40#else
41# include <wchar.h>
42# define MEMSET wmemset
43# define CHAR wchar_t
44# define UCHAR wchar_t
45# define SIMPLE_MEMSET simple_wmemset
46# define MEMCMP wmemcmp
47# define BIG_CHAR WCHAR_MAX
48#endif /* WIDE */
49
50CHAR *SIMPLE_MEMSET (CHAR *, int, size_t);
51
52#ifdef TEST_BZERO
53typedef void (*proto_t) (char *, size_t);
54void simple_bzero (char *, size_t);
55void builtin_bzero (char *, size_t);
56
57IMPL (simple_bzero, 0)
58IMPL (builtin_bzero, 0)
59IMPL (bzero, 1)
60
61void
62simple_bzero (char *s, size_t n)
63{
64 SIMPLE_MEMSET (s, 0, n);
65}
66
67void
68builtin_bzero (char *s, size_t n)
69{
70 __builtin_bzero (s, n);
71}
72#else
73typedef CHAR *(*proto_t) (CHAR *, int, size_t);
74
75IMPL (SIMPLE_MEMSET, 0)
76# ifndef WIDE
77char *builtin_memset (char *, int, size_t);
78IMPL (builtin_memset, 0)
79# endif /* !WIDE */
80IMPL (MEMSET, 1)
81
82# ifndef WIDE
83char *
84builtin_memset (char *s, int c, size_t n)
85{
86 return __builtin_memset (s, c, n);
87}
88# endif /* !WIDE */
89#endif /* !TEST_BZERO */
90
91CHAR *
92inhibit_loop_to_libcall
93SIMPLE_MEMSET (CHAR *s, int c, size_t n)
94{
95 CHAR *r = s, *end = s + n;
96 while (r < end)
97 *r++ = c;
98 return s;
99}
100
101static void
102do_one_test (impl_t *impl, CHAR *s, int c __attribute ((unused)), size_t n)
103{
104 CHAR tstbuf[n];
105#ifdef TEST_BZERO
106 simple_bzero (tstbuf, n);
107 CALL (impl, s, n);
108 if (memcmp (s, tstbuf, n) != 0)
109#else
110 CHAR *res = CALL (impl, s, c, n);
111 if (res != s
112 || SIMPLE_MEMSET (tstbuf, c, n) != tstbuf
113 || MEMCMP (s, tstbuf, n) != 0)
114#endif /* !TEST_BZERO */
115 {
116 error (0, 0, "Wrong result in function %s", impl->name);
117 ret = 1;
118 return;
119 }
120}
121
122static void
123do_test (size_t align, int c, size_t len)
124{
125 align &= 7;
126 if ((align + len) * sizeof (CHAR) > page_size)
127 return;
128
129 FOR_EACH_IMPL (impl, 0)
130 do_one_test (impl, (CHAR *) (buf1) + align, c, len);
131}
132
133#ifndef TEST_BZERO
134static void
135do_random_tests (void)
136{
137 size_t i, j, k, n, align, len, size;
138 int c, o;
139 UCHAR *p, *res;
140 UCHAR *p2 = (UCHAR *) buf2;
141
142 for (i = 0; i < 65536 / sizeof (CHAR); ++i)
143 p2[i] = random () & BIG_CHAR;
144
145 for (n = 0; n < ITERATIONS; n++)
146 {
147 if ((random () & 31) == 0)
148 size = 65536 / sizeof (CHAR);
149 else
150 size = 512;
151 p = (UCHAR *) (buf1 + page_size) - size;
152 len = random () & (size - 1);
153 align = size - len - (random () & 31);
154 if (align > size)
155 align = size - len;
156 if ((random () & 7) == 0)
157 align &= ~63;
158 if ((random () & 7) == 0)
159 c = 0;
160 else
161 c = random () & BIG_CHAR;
162 o = random () & BIG_CHAR;
163 if (o == c)
164 o = (c + 1) & BIG_CHAR;
165 j = len + align + 128;
166 if (j > size)
167 j = size;
168 if (align >= 128)
169 k = align - 128;
170 else
171 k = 0;
172 for (i = k; i < align; ++i)
173 p[i] = o;
174 for (i = align + len; i < j; ++i)
175 p[i] = o;
176
177 FOR_EACH_IMPL (impl, 1)
178 {
179 for (i = 0; i < len; ++i)
180 {
181 p[i + align] = p2[i];
182 if (p[i + align] == c)
183 p[i + align] = o;
184 }
185 res = (UCHAR *) CALL (impl, (CHAR *) p + align, c, len);
186 if (res != p + align)
187 {
188 error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %d, %zd) %p != %p",
189 n, impl->name, align, c, len, res, p + align);
190 ret = 1;
191 }
192 for (i = k; i < align; ++i)
193 if (p[i] != o)
194 {
195 error (0, 0, "Iteration %zd - garbage before %s (%zd, %d, %zd)",
196 n, impl->name, align, c, len);
197 ret = 1;
198 break;
199 }
200 for (; i < align + len; ++i)
201 if (p[i] != c)
202 {
203 error (0, 0, "Iteration %zd - not cleared correctly %s (%zd, %d, %zd)",
204 n, impl->name, align, c, len);
205 ret = 1;
206 break;
207 }
208 for (; i < j; ++i)
209 if (p[i] != o)
210 {
211 error (0, 0, "Iteration %zd - garbage after %s (%zd, %d, %zd)",
212 n, impl->name, align, c, len);
213 ret = 1;
214 break;
215 }
216 }
217 }
218}
219#endif /* !TEST_BZERO */
220
221int
222test_main (void)
223{
224 size_t i;
225 int c = 0;
226
227 test_init ();
228
229 printf ("%24s", "");
230 FOR_EACH_IMPL (impl, 0)
231 printf ("\t%s", impl->name);
232 putchar ('\n');
233
234#ifndef TEST_BZERO
235 for (c = -65; c <= 130; c += 65)
236#endif
237 {
238 for (i = 0; i < 18; ++i)
239 do_test (0, c, 1 << i);
240 for (i = 1; i < 32; ++i)
241 {
242 do_test (i, c, i);
243 if (i & (i - 1))
244 do_test (0, c, i);
245 }
246 do_test (1, c, 14);
247 do_test (3, c, 1024);
248 do_test (4, c, 64);
249 do_test (2, c, 25);
250 }
251
252#ifndef TEST_BZERO
253 do_random_tests ();
254#endif
255
256 return ret;
257}
258
259#include "../test-skeleton.c"