1*5ad8bbeeSAlvin Wong // RUN: %clang_cl_asan %Od %MT -o %t %s
2673dc3d4SNico Weber // RUN: %env_asan_opts=windows_hook_rtl_allocators=true %run %t 2>&1 | FileCheck %s
3673dc3d4SNico Weber // UNSUPPORTED: asan-64-bits
4673dc3d4SNico Weber #include <cassert>
5673dc3d4SNico Weber #include <iostream>
6673dc3d4SNico Weber #include <windows.h>
7673dc3d4SNico Weber
main()8673dc3d4SNico Weber int main() {
9673dc3d4SNico Weber void *ptr = malloc(0);
10673dc3d4SNico Weber if (ptr)
11673dc3d4SNico Weber std::cerr << "allocated!\n";
12673dc3d4SNico Weber ((char *)ptr)[0] = '\xff'; //check this 'allocate 1 instead of 0' hack hasn't changed
13673dc3d4SNico Weber
14673dc3d4SNico Weber free(ptr);
15673dc3d4SNico Weber
16673dc3d4SNico Weber /*
17673dc3d4SNico Weber HeapAlloc hack for our asan interceptor is to change 0
18673dc3d4SNico Weber sized allocations to size 1 to avoid weird inconsistencies
19673dc3d4SNico Weber between how realloc and heaprealloc handle 0 size allocations.
20673dc3d4SNico Weber
21673dc3d4SNico Weber Note this test relies on these instructions being intercepted.
22673dc3d4SNico Weber Without ASAN HeapRealloc on line 27 would return a ptr whose
23673dc3d4SNico Weber HeapSize would be 0. This test makes sure that the underlying behavior
24673dc3d4SNico Weber of our hack hasn't changed underneath us.
25673dc3d4SNico Weber
26673dc3d4SNico Weber We can get rid of the test (or change it to test for the correct
27673dc3d4SNico Weber behavior) once we fix the interceptor or write a different allocator
28673dc3d4SNico Weber to handle 0 sized allocations properly by default.
29673dc3d4SNico Weber
30673dc3d4SNico Weber */
31673dc3d4SNico Weber ptr = HeapAlloc(GetProcessHeap(), 0, 0);
32673dc3d4SNico Weber if (!ptr)
33673dc3d4SNico Weber return 1;
34673dc3d4SNico Weber void *ptr2 = HeapReAlloc(GetProcessHeap(), 0, ptr, 0);
35673dc3d4SNico Weber if (!ptr2)
36673dc3d4SNico Weber return 1;
37673dc3d4SNico Weber size_t heapsize = HeapSize(GetProcessHeap(), 0, ptr2);
38673dc3d4SNico Weber if (heapsize != 1) { // will be 0 without ASAN turned on
39673dc3d4SNico Weber std::cerr << "HeapAlloc size failure! " << heapsize << " != 1\n";
40673dc3d4SNico Weber return 1;
41673dc3d4SNico Weber }
42673dc3d4SNico Weber void *ptr3 = HeapReAlloc(GetProcessHeap(), 0, ptr2, 3);
43673dc3d4SNico Weber if (!ptr3)
44673dc3d4SNico Weber return 1;
45673dc3d4SNico Weber heapsize = HeapSize(GetProcessHeap(), 0, ptr3);
46673dc3d4SNico Weber
47673dc3d4SNico Weber if (heapsize != 3) {
48673dc3d4SNico Weber std::cerr << "HeapAlloc size failure! " << heapsize << " != 3\n";
49673dc3d4SNico Weber return 1;
50673dc3d4SNico Weber }
51673dc3d4SNico Weber HeapFree(GetProcessHeap(), 0, ptr3);
52673dc3d4SNico Weber return 0;
53673dc3d4SNico Weber }
54673dc3d4SNico Weber
55673dc3d4SNico Weber // CHECK: allocated!
56673dc3d4SNico Weber // CHECK-NOT: heap-buffer-overflow
57673dc3d4SNico Weber // CHECK-NOT: AddressSanitizer
58673dc3d4SNico Weber // CHECK-NOT: HeapAlloc size failure!
59