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) {
10 free(mem);
11}
12
13__attribute__((noinline)) void baz(void *mem) {
14 free(mem);
15}
16
17__attribute__((noinline)) void bar(void *mem) {
18 *(long*)((char*)mem + ACCESS_OFFSET) = 42;
19}
20
21int main() {
22 void *mem = malloc(100);
23 baz(mem);
24 mem = malloc(100);
25 foo(mem);
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