1 // RUN: %clang_tsan -O1 %s -o %t 2 // RUN: %deflake %run %t | FileCheck %s --check-prefix=CHECK-NOZUPP 3 // RUN: %env_tsan_opts=suppressions='%s.supp':print_suppressions=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SUPP 4 5 #include "test.h" 6 7 int *mem; 8 pthread_mutex_t mtx; 9 Thread1(void * x)10void *Thread1(void *x) { 11 pthread_mutex_lock(&mtx); 12 free(mem); 13 pthread_mutex_unlock(&mtx); 14 barrier_wait(&barrier); 15 return NULL; 16 } 17 Thread2(void * x)18void *Thread2(void *x) { 19 barrier_wait(&barrier); 20 pthread_mutex_lock(&mtx); 21 mem[0] = 42; 22 pthread_mutex_unlock(&mtx); 23 return NULL; 24 } 25 main()26int main() { 27 barrier_init(&barrier, 2); 28 mem = (int*)malloc(100); 29 pthread_mutex_init(&mtx, 0); 30 pthread_t t; 31 pthread_create(&t, NULL, Thread1, NULL); 32 Thread2(0); 33 pthread_join(t, NULL); 34 pthread_mutex_destroy(&mtx); 35 return 0; 36 } 37 38 // CHECK-NOZUPP: WARNING: ThreadSanitizer: heap-use-after-free 39 // CHECK-NOZUPP: Write of size 4 at {{.*}} by main thread{{.*}}: 40 // CHECK-NOZUPP: #0 Thread2 41 // CHECK-NOZUPP: #1 main 42 // CHECK-NOZUPP: Previous write of size 8 at {{.*}} by thread T1{{.*}}: 43 // CHECK-NOZUPP: #0 free 44 // CHECK-NOZUPP: #{{(1|2)}} Thread1 45 // CHECK-NOZUPP: SUMMARY: ThreadSanitizer: heap-use-after-free{{.*}}Thread2 46 // CHECK-SUPP: ThreadSanitizer: Matched 1 suppressions 47 // CHECK-SUPP: 1 race:^Thread2$ 48