1673dc3d4SNico Weber // Check that free hook doesn't conflict with Realloc.
2673dc3d4SNico Weber // RUN: %clangxx_asan -O2 %s -o %t
3673dc3d4SNico Weber // RUN: %run %t 2>&1 | FileCheck %s
4673dc3d4SNico Weber 
5673dc3d4SNico Weber #include <stdlib.h>
6673dc3d4SNico Weber #include <unistd.h>
7673dc3d4SNico Weber #include <sanitizer/allocator_interface.h>
8673dc3d4SNico Weber 
9673dc3d4SNico Weber static void *glob_ptr;
10673dc3d4SNico Weber 
11*1850a7a9SRoy Sundahl // Required for dyld macOS 12.0+
12*1850a7a9SRoy Sundahl #if (__APPLE__)
13*1850a7a9SRoy Sundahl __attribute__((weak))
14*1850a7a9SRoy Sundahl #endif
15*1850a7a9SRoy Sundahl extern "C" void
__sanitizer_free_hook(const volatile void * ptr)16*1850a7a9SRoy Sundahl __sanitizer_free_hook(const volatile void *ptr) {
17673dc3d4SNico Weber   if (ptr == glob_ptr) {
18673dc3d4SNico Weber     *(int*)ptr = 0;
19673dc3d4SNico Weber     write(1, "FreeHook\n", sizeof("FreeHook\n"));
20673dc3d4SNico Weber   }
21673dc3d4SNico Weber }
22673dc3d4SNico Weber 
main()23673dc3d4SNico Weber int main() {
24673dc3d4SNico Weber   int *x = (int*)malloc(100);
25673dc3d4SNico Weber   x[0] = 42;
26673dc3d4SNico Weber   glob_ptr = x;
27673dc3d4SNico Weber   int *y = (int*)realloc(x, 200);
28673dc3d4SNico Weber   // Verify that free hook was called and didn't spoil the memory.
29673dc3d4SNico Weber   if (y[0] != 42) {
30673dc3d4SNico Weber     _exit(1);
31673dc3d4SNico Weber   }
32673dc3d4SNico Weber   write(1, "Passed\n", sizeof("Passed\n"));
33673dc3d4SNico Weber   free(y);
34673dc3d4SNico Weber   // CHECK: FreeHook
35673dc3d4SNico Weber   // CHECK: Passed
36673dc3d4SNico Weber   return 0;
37673dc3d4SNico Weber }
38