1 /** memory function test
9 #if defined(__SDCC_stm8) || defined(PORT_HOST) || defined(__SDCC_ds390) || \
10 (defined(__SDCC_mcs51) && (defined(__SDCC_MODEL_LARGE) || defined(__SDCC_MODEL_HUGE))) || \
11 defined(__SDCC_z80) || defined(__SDCC_z80n) || defined(__SDCC_z180) || defined(__SDCC_r2k) || defined(__SDCC_r2ka) || defined(__SDCC_r3ka)
16 #define BUILTINS_{builtins} 1
17 #if defined(BUILTINS_off) && !defined(__SDCC_pdk14)
27 /* Note: the majority of library function calls purposefully do not assign or
28 * test the return value. This is so that, on some ports (e.g. z80), the
29 * built-in functions are used and tested. */
31 unsigned char destination
[9];
32 const unsigned char source
[9] = {0, 1, 2, 3};
36 // Some of these tests intentionally do not check the return value of functions:
37 // Some backends use built-ins when the return value is not used, but fall back
38 // to a library version otherwise. So we need tests with unused return value to
39 // test the built-in. Similarly, code paths for built-ns are different depending
40 // on the last parameter being a literal vs. not. So we need to test both with a
41 // literal and a volatile variable.
45 /* Local stack variables */
46 volatile size_t zero
= 0;
47 volatile size_t one
= 1;
49 ASSERT(source
[0] == 0);
53 memset(destination
, c
, one
);
54 ASSERT(destination
[0] == 8);
55 memset(destination
, c
, 3);
56 ASSERT(destination
[2] == 8);
58 memset(destination
, 42, 3);
59 ASSERT(destination
[0] == 42);
60 ASSERT(destination
[2] == 42);
61 ASSERT(destination
[3] == 23);
62 memset(destination
, 23, 1);
63 ASSERT(destination
[0] == 23);
64 ASSERT(destination
[1] == 42);
65 memset(destination
, 42, 1);
67 memcpy(destination
, source
, 0);
68 ASSERT(destination
[0] == 42);
69 memcpy(destination
, source
, zero
);
70 ASSERT(destination
[0] == 42);
71 memcpy(destination
+ 1, source
+ 1, 2);
72 ASSERT(destination
[0] == 42);
73 ASSERT(destination
[2] == source
[2]);
74 ASSERT(destination
[3] == 23);
75 memcpy(destination
, source
, one
);
76 ASSERT(destination
[0] == 0);
77 memset(destination
, 5, 9);
78 memcpy(destination
, source
, 8);
79 ASSERT(destination
[7] == source
[7]);
80 ASSERT(destination
[8] == 5);
81 memset(destination
, 5, 9);
82 memcpy(destination
, source
, 3);
83 ASSERT(destination
[2] == source
[2]);
84 ASSERT(destination
[3] == 5);
86 memcpy(destination
, source
, 4);
87 ASSERT(memcmp(destination
, source
, 4) == 0);
89 #ifndef __SDCC_pdk14 // Lack of memory
90 #if !(defined (__SDCC_pdk15) && defined(__SDCC_STACK_AUTO)) // Lack of code memory
93 ret
= memmove(destination
, "abcdefgh", 9); // Full copy
94 ASSERT(strcmp(destination
, "abcdefgh") == 0);
95 ASSERT(ret
== destination
);
97 ret
= memmove(destination
+ 1, "123", 3); // Sub copy with offset
98 ASSERT(strcmp(destination
, "a123efgh") == 0);
99 ASSERT(ret
== destination
+ 1);
101 ret
= memmove(destination
, source
, 0); // Zero count, changes nothing
102 ASSERT(strcmp(destination
, "a123efgh") == 0);
103 ASSERT(ret
== destination
);
105 ret
= memmove(destination
+ 1, destination
, 7); // Overlap to right
106 ASSERT(strcmp(destination
, "aa123efg") == 0);
107 ASSERT(ret
== destination
+ 1);
109 ret
= memmove(destination
, destination
+ 1, 8); // Overlap to left
110 ASSERT(strcmp(destination
, "a123efg") == 0);
111 ASSERT(ret
== destination
);
113 ret
= memmove(destination
, destination
, 9); // 100% overlap
114 ASSERT(strcmp(destination
, "a123efg") == 0);
115 ASSERT(ret
== destination
);
118 memcpy(destination
, source
, 4);
119 ASSERT(NULL
== memchr(destination
, 5, 4));
120 ASSERT(destination
== memchr(destination
, 0, 4));
121 ASSERT(destination
+ 3 == memchr(destination
, 3, 4));
124 ASSERT(strlen("test") == 4);
125 ASSERT(strlen("t") == 1);
126 ASSERT(strlen("") == 0);
132 ASSERT(memccpy(destination
, source
, 2, 4) == destination
+ 3);
133 ASSERT(destination
[2] == 2);
134 ASSERT(destination
[3] == 0);
143 unsigned char largedest
[1050];
144 unsigned char largesource
[1050];
151 memset(largedest
, 0, 1050);
152 memset(largedest
, 1, 4);
153 memset(largesource
, 2, 1050);
155 memcpy(largedest
+ 1, largesource
, 1024);
157 ASSERT(largedest
[0] == 1);
158 ASSERT(largedest
[1] == 2);
159 ASSERT(largedest
[1024] == 2);
160 ASSERT(largedest
[1025] == 0);
162 /* Test strlen with large string */
163 memset(largesource
, 'x', 999);
164 largesource
[999] = '\0';
165 ASSERT(strlen(largesource
) == 999);
167 /* Test memmove() with large (>255) counts */
168 unsigned char *ls_a
= largesource
+ 0;
169 unsigned char *ls_b
= largesource
+ 500;
171 ret
= memset(ls_a
, 'a', 500);
173 ret
= memset(ls_b
, 'b', 500);
175 ASSERT(ls_a
[0] == 'a' && ls_a
[499] == 'a');
176 ASSERT(ls_b
[0] == 'b' && ls_b
[499] == 'b');
179 ret
= memmove(largedest
, ls_a
, 500); // put 'a' in first half of dest
180 ASSERT(ret
== largedest
);
181 ASSERT(memcmp(largedest
, ls_a
, 500) == 0);
184 ret
= memmove(largedest
+ 500, largedest
, 500); // copy to last half (no overlap)
185 ASSERT(ret
== largedest
+ 500);
186 ASSERT(memcmp(largedest
+ 500, ls_a
, 500) == 0);
189 ret
= memmove(largedest
+ 250, ls_b
, 500); // put 'b' in middle half
190 ASSERT(ret
== largedest
+ 250);
191 ASSERT(memcmp(largedest
, ls_a
, 250) == 0);
192 ASSERT(memcmp(largedest
+ 250, ls_b
, 500) == 0);
193 ASSERT(memcmp(largedest
+ 750, ls_a
, 250) == 0);
196 ret
= memmove(largedest
+ 250, largedest
+ 500, 500); // overlap to left
197 ASSERT(ret
== largedest
+ 250);
198 ASSERT(memcmp(largedest
, ls_a
, 250) == 0);
199 ASSERT(memcmp(largedest
+ 250, ls_b
, 250) == 0);
200 ASSERT(memcmp(largedest
+ 500, ls_a
, 500) == 0);
203 ret
= memmove(largedest
+ 500, largedest
+ 250, 500); // overlap to right
204 ASSERT(ret
== largedest
+ 500);
205 ASSERT(memcmp(largedest
, ls_a
, 250) == 0);
206 ASSERT(memcmp(largedest
+ 250, ls_b
, 500) == 0);
207 ASSERT(memcmp(largedest
+ 750, ls_a
, 250) == 0);
212 void testRetVal(void)
215 volatile size_t one
= 1;
216 volatile size_t zero
= 0;
217 ASSERT(destination
== memcpy(destination
, source
, sizeof(source
)));
218 ASSERT(destination
== memcpy(destination
, source
, 0));
219 ASSERT(destination
== memcpy(destination
, source
, zero
));
220 ASSERT(destination
== memcpy(destination
, source
, one
));
221 ASSERT(destination
== memset(destination
, (int)one
, zero
));
222 ASSERT(destination
== memset(destination
, (int)zero
, 0));
223 ASSERT(destination
== memset(destination
, (int)zero
, one
));
224 ASSERT(destination
== memset(destination
, (int)one
, sizeof(destination
)));
225 ASSERT(&one
== memset(&one
, 0, sizeof(one
)));
226 ASSERT(&zero
== memcpy(&zero
, &one
, sizeof(one
)));