gdiplus: Added GdipRotateTextureTransform.
[wine] / dlls / msvcrt / tests / heap.c
1 /*
2  * Unit test suite for memory functions
3  *
4  * Copyright 2003 Dimitrie O. Paun
5  *
6  * This 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  * This 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 this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <stdlib.h>
22 #include <malloc.h>
23 #include <errno.h>
24 #include "wine/test.h"
25
26 static void (*p_aligned_free)(void*) = NULL;
27 static void * (*p_aligned_malloc)(size_t,size_t) = NULL;
28 static void * (*p_aligned_offset_malloc)(size_t,size_t,size_t) = NULL;
29 static void * (*p_aligned_realloc)(void*,size_t,size_t) = NULL;
30 static void * (*p_aligned_offset_realloc)(void*,size_t,size_t,size_t) = NULL;
31
32 static void test_aligned_malloc(size_t size, size_t alignment)
33 {
34     void *mem;
35
36     mem = p_aligned_malloc(size, alignment);
37
38     if ((alignment & (alignment - 1)) == 0)
39         ok(mem != NULL, "_aligned_malloc(%d, %d) failed\n", size, alignment);
40     else
41         ok(mem == NULL, "_aligned_malloc(%d, %d) should have failed\n", size, alignment);
42
43     if (mem)
44     {
45         ok(((DWORD_PTR)mem & (alignment ? alignment - 1 : 0)) == 0,
46            "_aligned_malloc(%d, %d) not aligned: %p\n", size, alignment, mem);
47         if (winetest_debug > 1)
48         {
49             void *saved;
50             saved = *(void **)((DWORD_PTR)((char *)mem - sizeof(void *)) & ~(sizeof(void *) - 1));
51             trace("_aligned_malloc(%3d, %3d) returns %p, saved = %p, diff = %d\n",
52                   size, alignment, mem, saved, (char *)saved - (char *)mem);
53         }
54         p_aligned_free(mem);
55     }
56     else
57         ok(errno == EINVAL, "_aligned_malloc(%d, %d) errno: %d != %d\n", size, alignment, errno, EINVAL);
58 }
59
60 static void test_aligned_offset_malloc(size_t size, size_t alignment, size_t offset)
61 {
62     void *mem;
63
64     mem = p_aligned_offset_malloc(size, alignment, offset);
65
66     if ((alignment & (alignment - 1)) == 0)
67         if (offset < size)
68             ok(mem != NULL, "_aligned_offset_malloc(%d, %d, %d) failed\n", size, alignment, offset);
69         else
70             ok(errno == EINVAL, "_aligned_offset_malloc(%d, %d, %d) errno: %d != %d\n", size, alignment, offset, errno, EINVAL);
71     else
72         ok(mem == NULL, "_aligned_offset_malloc(%d, %d, %d) should have failed\n", size, alignment, offset);
73
74     if (mem)
75     {
76         ok(((DWORD_PTR)((char *)mem + offset) & (alignment ? alignment - 1 : 0)) == 0,
77            "_aligned_offset_malloc(%d, %d, %d) not aligned: %p\n", size, alignment, offset, mem);
78         if (winetest_debug > 1)
79         {
80             void *saved;
81             saved = *(void **)((DWORD_PTR)((char *)mem - sizeof(void *)) & ~(sizeof(void *) - 1));
82             trace("_aligned_offset_malloc(%3d, %3d, %3d) returns %p, saved = %p, diff = %d\n",
83                   size, alignment, offset, mem, saved, (char *)saved - (char *)mem);
84         }
85         p_aligned_free(mem);
86     }
87     else
88         ok(errno == EINVAL, "_aligned_offset_malloc(%d, %d, %d) errno: %d != %d\n", size, alignment, offset, errno, EINVAL);
89 }
90
91 static void test_aligned_realloc(size_t size1, size_t size2, size_t alignment)
92 {
93     void *mem, *mem1, *mem2;
94
95     mem = p_aligned_malloc(size1, alignment);
96
97     if ((alignment & (alignment - 1)) == 0)
98         ok(mem != NULL, "_aligned_malloc(%d, %d) failed\n", size1, alignment);
99     else
100         ok(mem == NULL, "_aligned_malloc(%d, %d) should have failed\n", size1, alignment);
101
102     if (mem)
103     {
104         mem1 = malloc(size1);
105         if (mem1)
106         {
107             int i;
108             for (i = 0; i < size1; i++)
109                 ((char *)mem)[i] = i + 1;
110             memcpy(mem1, mem, size1);
111         }
112
113         ok(((DWORD_PTR)mem & (alignment ? alignment - 1 : 0)) == 0,
114            "_aligned_malloc(%d, %d) not aligned: %p\n", size1, alignment, mem);
115         if (winetest_debug > 1)
116         {
117             void *saved;
118             saved = *(void **)((DWORD_PTR)((char *)mem - sizeof(void *)) & ~(sizeof(void *) - 1));
119             trace("_aligned_malloc(%3d, %3d) returns %p, saved = %p, diff = %d\n",
120                   size1, alignment, mem, saved, (char *)saved - (char *)mem);
121         }
122
123         mem2 = p_aligned_realloc(mem, size2, alignment);
124
125         ok(mem2 != NULL, "_aligned_realloc(%p, %d, %d) failed\n", mem, size2, alignment);
126
127         if (mem2)
128         {
129             ok(((DWORD_PTR)mem2 & (alignment ? alignment - 1 : 0)) == 0,
130                "_aligned_realloc(%p, %d, %d) not aligned: %p\n", mem, size2, alignment, mem2);
131             if (winetest_debug > 1)
132             {
133                 void *saved;
134                 saved = *(void **)((DWORD_PTR)((char *)mem2 - sizeof(void *)) & ~(sizeof(void *) - 1));
135                 trace("_aligned_realloc(%p, %3d, %3d) returns %p, saved = %p, diff = %d\n",
136                       mem, size2, alignment, mem2, saved, (char *)saved - (char *)mem2);
137             }
138             if (mem1)
139             {
140                 ok(memcmp(mem2, mem1, min(size1, size2))==0, "_aligned_realloc(%p, %d, %d) has different data\n", mem, size2, alignment);
141                 if (memcmp(mem2, mem1, min(size1, size2)) && winetest_debug > 1)
142                 {
143                     int i;
144                     for (i = 0; i < min(size1, size2); i++)
145                     {
146                         if (((char *)mem2)[i] != ((char *)mem1)[i])
147                             trace("%d: %02x != %02x\n", i, ((char *)mem2)[i] & 0xff, ((char *)mem1)[i] & 0xff);
148                     }
149                 }
150             }
151             p_aligned_free(mem2);
152         } else {
153             ok(errno == EINVAL, "_aligned_realloc(%p, %d, %d) errno: %d != %d\n", mem, size2, alignment, errno, EINVAL);
154             p_aligned_free(mem);
155         }
156
157         free(mem1);
158     }
159     else
160         ok(errno == EINVAL, "_aligned_malloc(%d, %d) errno: %d != %d\n", size1, alignment, errno, EINVAL);
161 }
162
163 static void test_aligned_offset_realloc(size_t size1, size_t size2, size_t alignment, size_t offset)
164 {
165     void *mem, *mem1, *mem2;
166
167     mem = p_aligned_offset_malloc(size1, alignment, offset);
168
169     if ((alignment & (alignment - 1)) == 0)
170         ok(mem != NULL, "_aligned_offset_malloc(%d, %d, %d) failed\n", size1, alignment, offset);
171     else
172         ok(mem == NULL, "_aligned_offset_malloc(%d, %d, %d) should have failed\n", size1, alignment, offset);
173
174     if (mem)
175     {
176         mem1 = malloc(size1);
177         if (mem1)
178         {
179             int i;
180             for (i = 0; i < size1; i++)
181                 ((char *)mem)[i] = i + 1;
182             memcpy(mem1, mem, size1);
183         }
184
185         ok(((DWORD_PTR)((char *)mem + offset) & (alignment ? alignment - 1 : 0)) == 0,
186            "_aligned_offset_malloc(%d, %d, %d) not aligned: %p\n", size1, alignment, offset, mem);
187         if (winetest_debug > 1)
188         {
189             void *saved;
190             saved = *(void **)((DWORD_PTR)((char *)mem - sizeof(void *)) & ~(sizeof(void *) - 1));
191             trace("_aligned_offset_malloc(%3d, %3d, %3d) returns %p, saved = %p, diff = %d\n",
192                   size1, alignment, offset, mem, saved, (char *)saved - (char *)mem);
193         }
194
195         mem2 = p_aligned_offset_realloc(mem, size2, alignment, offset);
196
197         ok(mem2 != NULL, "_aligned_offset_realloc(%p, %d, %d, %d) failed\n", mem, size2, alignment, offset);
198
199         if (mem2)
200         {
201             ok(((DWORD_PTR)((char *)mem + offset) & (alignment ? alignment - 1 : 0)) == 0,
202                "_aligned_offset_realloc(%p, %d, %d, %d) not aligned: %p\n", mem, size2, alignment, offset, mem2);
203             if (winetest_debug > 1)
204             {
205                 void *saved;
206                 saved = *(void **)((DWORD_PTR)((char *)mem2 - sizeof(void *)) & ~(sizeof(void *) - 1));
207                 trace("_aligned_offset_realloc(%p, %3d, %3d, %3d) returns %p, saved = %p, diff = %d\n",
208                       mem, size2, alignment, offset, mem2, saved, (char *)saved - (char *)mem2);
209             }
210             if (mem1)
211             {
212                 ok(memcmp(mem2, mem1, min(size1, size2))==0, "_aligned_offset_realloc(%p, %d, %d, %d) has different data\n", mem, size2, alignment, offset);
213                 if (memcmp(mem2, mem1, min(size1, size2)) && winetest_debug > 1)
214                 {
215                     int i;
216                     for (i = 0; i < min(size1, size2); i++)
217                     {
218                         if (((char *)mem2)[i] != ((char *)mem1)[i])
219                             trace("%d: %02x != %02x\n", i, ((char *)mem2)[i] & 0xff, ((char *)mem1)[i] & 0xff);
220                     }
221                 }
222             }
223             p_aligned_free(mem2);
224         } else {
225             ok(errno == EINVAL, "_aligned_offset_realloc(%p, %d, %d, %d) errno: %d != %d\n", mem, size2, alignment, offset, errno, EINVAL);
226             p_aligned_free(mem);
227         }
228
229         free(mem1);
230     }
231     else
232         ok(errno == EINVAL, "_aligned_offset_malloc(%d, %d) errno: %d != %d\n", size1, alignment, errno, EINVAL);
233 }
234
235 static void test_aligned(void)
236 {
237     HMODULE msvcrt = GetModuleHandle("msvcrt.dll");
238
239     if (msvcrt == NULL)
240         return;
241
242     p_aligned_free = (void*)GetProcAddress(msvcrt, "_aligned_free");
243     p_aligned_malloc = (void*)GetProcAddress(msvcrt, "_aligned_malloc");
244     p_aligned_offset_malloc = (void*)GetProcAddress(msvcrt, "_aligned_offset_malloc");
245     p_aligned_realloc = (void*)GetProcAddress(msvcrt, "_aligned_realloc");
246     p_aligned_offset_realloc = (void*)GetProcAddress(msvcrt, "_aligned_offset_realloc");
247
248     if (!p_aligned_free || !p_aligned_malloc || !p_aligned_offset_malloc || !p_aligned_realloc || !p_aligned_offset_realloc)
249     {
250         skip("aligned memory tests skipped\n");
251         return;
252     }
253
254     test_aligned_malloc(256, 0);
255     test_aligned_malloc(256, 1);
256     test_aligned_malloc(256, 2);
257     test_aligned_malloc(256, 3);
258     test_aligned_malloc(256, 4);
259     test_aligned_malloc(256, 8);
260     test_aligned_malloc(256, 16);
261     test_aligned_malloc(256, 32);
262     test_aligned_malloc(256, 64);
263     test_aligned_malloc(256, 127);
264     test_aligned_malloc(256, 128);
265
266     test_aligned_offset_malloc(256, 0, 0);
267     test_aligned_offset_malloc(256, 1, 0);
268     test_aligned_offset_malloc(256, 2, 0);
269     test_aligned_offset_malloc(256, 3, 0);
270     test_aligned_offset_malloc(256, 4, 0);
271     test_aligned_offset_malloc(256, 8, 0);
272     test_aligned_offset_malloc(256, 16, 0);
273     test_aligned_offset_malloc(256, 32, 0);
274     test_aligned_offset_malloc(256, 64, 0);
275     test_aligned_offset_malloc(256, 127, 0);
276     test_aligned_offset_malloc(256, 128, 0);
277
278     test_aligned_offset_malloc(256, 0, 4);
279     test_aligned_offset_malloc(256, 1, 4);
280     test_aligned_offset_malloc(256, 2, 4);
281     test_aligned_offset_malloc(256, 3, 4);
282     test_aligned_offset_malloc(256, 4, 4);
283     test_aligned_offset_malloc(256, 8, 4);
284     test_aligned_offset_malloc(256, 16, 4);
285     test_aligned_offset_malloc(256, 32, 4);
286     test_aligned_offset_malloc(256, 64, 4);
287     test_aligned_offset_malloc(256, 127, 4);
288     test_aligned_offset_malloc(256, 128, 4);
289
290     test_aligned_offset_malloc(256, 8, 7);
291     test_aligned_offset_malloc(256, 8, 9);
292     test_aligned_offset_malloc(256, 8, 16);
293     test_aligned_offset_malloc(256, 8, 17);
294     test_aligned_offset_malloc(256, 8, 254);
295     test_aligned_offset_malloc(256, 8, 255);
296     test_aligned_offset_malloc(256, 8, 256);
297     test_aligned_offset_malloc(256, 8, 512);
298
299     test_aligned_realloc(256, 512, 0);
300     test_aligned_realloc(256, 128, 0);
301     test_aligned_realloc(256, 512, 4);
302     test_aligned_realloc(256, 128, 4);
303     test_aligned_realloc(256, 512, 8);
304     test_aligned_realloc(256, 128, 8);
305     test_aligned_realloc(256, 512, 16);
306     test_aligned_realloc(256, 128, 16);
307     test_aligned_realloc(256, 512, 32);
308     test_aligned_realloc(256, 128, 32);
309     test_aligned_realloc(256, 512, 64);
310     test_aligned_realloc(256, 128, 64);
311
312     test_aligned_offset_realloc(256, 512, 0, 0);
313     test_aligned_offset_realloc(256, 128, 0, 0);
314     test_aligned_offset_realloc(256, 512, 4, 0);
315     test_aligned_offset_realloc(256, 128, 4, 0);
316     test_aligned_offset_realloc(256, 512, 8, 0);
317     test_aligned_offset_realloc(256, 128, 8, 0);
318     test_aligned_offset_realloc(256, 512, 16, 0);
319     test_aligned_offset_realloc(256, 128, 16, 0);
320     test_aligned_offset_realloc(256, 512, 32, 0);
321     test_aligned_offset_realloc(256, 128, 32, 0);
322     test_aligned_offset_realloc(256, 512, 64, 0);
323     test_aligned_offset_realloc(256, 128, 64, 0);
324
325     test_aligned_offset_realloc(256, 512, 0, 4);
326     test_aligned_offset_realloc(256, 128, 0, 4);
327     test_aligned_offset_realloc(256, 512, 4, 4);
328     test_aligned_offset_realloc(256, 128, 4, 4);
329     test_aligned_offset_realloc(256, 512, 8, 4);
330     test_aligned_offset_realloc(256, 128, 8, 4);
331     test_aligned_offset_realloc(256, 512, 16, 4);
332     test_aligned_offset_realloc(256, 128, 16, 4);
333     test_aligned_offset_realloc(256, 512, 32, 4);
334     test_aligned_offset_realloc(256, 128, 32, 4);
335     test_aligned_offset_realloc(256, 512, 64, 4);
336     test_aligned_offset_realloc(256, 128, 64, 4);
337
338     test_aligned_offset_realloc(256, 512, 0, 8);
339     test_aligned_offset_realloc(256, 128, 0, 8);
340     test_aligned_offset_realloc(256, 512, 4, 8);
341     test_aligned_offset_realloc(256, 128, 4, 8);
342     test_aligned_offset_realloc(256, 512, 8, 8);
343     test_aligned_offset_realloc(256, 128, 8, 8);
344     test_aligned_offset_realloc(256, 512, 16, 8);
345     test_aligned_offset_realloc(256, 128, 16, 8);
346     test_aligned_offset_realloc(256, 512, 32, 8);
347     test_aligned_offset_realloc(256, 128, 32, 8);
348     test_aligned_offset_realloc(256, 512, 64, 8);
349     test_aligned_offset_realloc(256, 128, 64, 8);
350
351     test_aligned_offset_realloc(256, 512, 0, 16);
352     test_aligned_offset_realloc(256, 128, 0, 16);
353     test_aligned_offset_realloc(256, 512, 4, 16);
354     test_aligned_offset_realloc(256, 128, 4, 16);
355     test_aligned_offset_realloc(256, 512, 8, 16);
356     test_aligned_offset_realloc(256, 128, 8, 16);
357     test_aligned_offset_realloc(256, 512, 16, 16);
358     test_aligned_offset_realloc(256, 128, 16, 16);
359     test_aligned_offset_realloc(256, 512, 32, 16);
360     test_aligned_offset_realloc(256, 128, 32, 16);
361     test_aligned_offset_realloc(256, 512, 64, 16);
362     test_aligned_offset_realloc(256, 128, 64, 16);
363
364     test_aligned_offset_realloc(256, 512, 0, 32);
365     test_aligned_offset_realloc(256, 128, 0, 32);
366     test_aligned_offset_realloc(256, 512, 4, 32);
367     test_aligned_offset_realloc(256, 128, 4, 32);
368     test_aligned_offset_realloc(256, 512, 8, 32);
369     test_aligned_offset_realloc(256, 128, 8, 32);
370     test_aligned_offset_realloc(256, 512, 16, 32);
371     test_aligned_offset_realloc(256, 128, 16, 32);
372     test_aligned_offset_realloc(256, 512, 32, 32);
373     test_aligned_offset_realloc(256, 128, 32, 32);
374     test_aligned_offset_realloc(256, 512, 64, 32);
375     test_aligned_offset_realloc(256, 128, 64, 32);
376
377     test_aligned_offset_realloc(256, 512, 0, 64);
378     test_aligned_offset_realloc(256, 128, 0, 64);
379     test_aligned_offset_realloc(256, 512, 4, 64);
380     test_aligned_offset_realloc(256, 128, 4, 64);
381     test_aligned_offset_realloc(256, 512, 8, 64);
382     test_aligned_offset_realloc(256, 128, 8, 64);
383     test_aligned_offset_realloc(256, 512, 16, 64);
384     test_aligned_offset_realloc(256, 128, 16, 64);
385     test_aligned_offset_realloc(256, 512, 32, 64);
386     test_aligned_offset_realloc(256, 128, 32, 64);
387     test_aligned_offset_realloc(256, 512, 64, 64);
388     test_aligned_offset_realloc(256, 128, 64, 64);
389
390     test_aligned_offset_realloc(256, 512, 0, 96);
391     test_aligned_offset_realloc(256, 128, 0, 96);
392     test_aligned_offset_realloc(256, 512, 4, 96);
393     test_aligned_offset_realloc(256, 128, 4, 96);
394     test_aligned_offset_realloc(256, 512, 8, 96);
395     test_aligned_offset_realloc(256, 128, 8, 96);
396     test_aligned_offset_realloc(256, 512, 16, 96);
397     test_aligned_offset_realloc(256, 128, 16, 96);
398     test_aligned_offset_realloc(256, 512, 32, 96);
399     test_aligned_offset_realloc(256, 128, 32, 96);
400     test_aligned_offset_realloc(256, 512, 64, 96);
401     test_aligned_offset_realloc(256, 128, 64, 96);
402
403     test_aligned_offset_realloc(256, 512, 0, 112);
404     test_aligned_offset_realloc(256, 128, 0, 112);
405     test_aligned_offset_realloc(256, 512, 4, 112);
406     test_aligned_offset_realloc(256, 128, 4, 112);
407     test_aligned_offset_realloc(256, 512, 8, 112);
408     test_aligned_offset_realloc(256, 128, 8, 112);
409     test_aligned_offset_realloc(256, 512, 16, 112);
410     test_aligned_offset_realloc(256, 128, 16, 112);
411     test_aligned_offset_realloc(256, 512, 32, 112);
412     test_aligned_offset_realloc(256, 128, 32, 112);
413     test_aligned_offset_realloc(256, 512, 64, 112);
414     test_aligned_offset_realloc(256, 128, 64, 112);
415 }
416
417 START_TEST(heap)
418 {
419     void *mem;
420
421     mem = malloc(0);
422     ok(mem != NULL, "memory not allocated for size 0\n");
423     free(mem);
424
425     mem = realloc(NULL, 10);
426     ok(mem != NULL, "memory not allocated\n");
427     
428     mem = realloc(mem, 20);
429     ok(mem != NULL, "memory not reallocated\n");
430  
431     mem = realloc(mem, 0);
432     ok(mem == NULL, "memory not freed\n");
433     
434     mem = realloc(NULL, 0);
435     ok(mem != NULL, "memory not (re)allocated for size 0\n");
436
437     free(mem);
438
439     test_aligned();
440 }