1// RUN: %clang_cl_asan %Od %MT -o %t %s
2// RUN: %env_asan_opts=windows_hook_rtl_allocators=true %run %t 2>&1 | FileCheck %s
3// UNSUPPORTED: asan-64-bits
4#include <cassert>
5#include <iostream>
6#include <windows.h>
7
8int main() {
9 void *ptr = malloc(size: 0);
10 if (ptr)
11 std::cerr << "allocated!\n";
12 ((char *)ptr)[0] = '\xff'; //check this 'allocate 1 instead of 0' hack hasn't changed
13
14 free(ptr: ptr);
15
16 /*
17 HeapAlloc hack for our asan interceptor is to change 0
18 sized allocations to size 1 to avoid weird inconsistencies
19 between how realloc and heaprealloc handle 0 size allocations.
20
21 Note this test relies on these instructions being intercepted.
22 Without ASAN HeapRealloc on line 27 would return a ptr whose
23 HeapSize would be 0. This test makes sure that the underlying behavior
24 of our hack hasn't changed underneath us.
25
26 We can get rid of the test (or change it to test for the correct
27 behavior) once we fix the interceptor or write a different allocator
28 to handle 0 sized allocations properly by default.
29
30 */
31 ptr = HeapAlloc(GetProcessHeap(), 0, 0);
32 if (!ptr)
33 return 1;
34 void *ptr2 = HeapReAlloc(GetProcessHeap(), 0, ptr, 0);
35 if (!ptr2)
36 return 1;
37 size_t heapsize = HeapSize(GetProcessHeap(), 0, ptr2);
38 if (heapsize != 1) { // will be 0 without ASAN turned on
39 std::cerr << "HeapAlloc size failure! " << heapsize << " != 1\n";
40 return 1;
41 }
42 void *ptr3 = HeapReAlloc(GetProcessHeap(), 0, ptr2, 3);
43 if (!ptr3)
44 return 1;
45 heapsize = HeapSize(GetProcessHeap(), 0, ptr3);
46
47 if (heapsize != 3) {
48 std::cerr << "HeapAlloc size failure! " << heapsize << " != 3\n";
49 return 1;
50 }
51 HeapFree(GetProcessHeap(), 0, ptr3);
52 return 0;
53}
54
55// CHECK: allocated!
56// CHECK-NOT: heap-buffer-overflow
57// CHECK-NOT: AddressSanitizer
58// CHECK-NOT: HeapAlloc size failure!
59

source code of compiler-rt/test/asan/TestCases/Windows/heaprealloc_alloc_zero.cpp