1 // RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
2 // RUN: %clang_tsan -O1 -DACCESS_OFFSET=4 %s -o %t && %deflake %run %t | FileCheck %s
3 #include <stdlib.h>
4 
5 #ifndef ACCESS_OFFSET
6 #define ACCESS_OFFSET 0
7 #endif
8 
9 __attribute__((noinline)) void foo(void *mem) {
Thread1(void * x)10   free(mem);
11 }
12 
13 __attribute__((noinline)) void baz(void *mem) {
14   free(mem);
15 }
16 
17 __attribute__((noinline)) void bar(void *mem) {
Thread2(void * x)18   *(long*)((char*)mem + ACCESS_OFFSET) = 42;
19 }
20 
21 int main() {
22   void *mem = malloc(100);
23   baz(mem);
24   mem = malloc(100);
25   foo(mem);
main()26   bar(mem);
27   return 0;
28 }
29 
30 // CHECK: WARNING: ThreadSanitizer: heap-use-after-free
31 // CHECK:   Write of size 8 at {{.*}} by main thread:
32 // CHECK:     #0 bar
33 // CHECK:     #1 main
34 // CHECK:   Previous write of size 8 at {{.*}} by main thread:
35 // CHECK:     #0 free
36 // CHECK:     #{{1|2}} foo
37 // CHECK:     #{{2|3}} main
38