1// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s
2#include <pthread.h>
3#include <stddef.h>
4#include <stdio.h>
5#include <string.h>
6#include <unistd.h>
7
8int x[4], y[4], z[4];
9
10void *MemCpyThread(void *a) {
11  memcpy((int*)a, z, 16);
12  return NULL;
13}
14
15void *MemMoveThread(void *a) {
16  memmove((int*)a, z, 16);
17  return NULL;
18}
19
20void *MemSetThread(void *a) {
21  sleep(1);
22  memset((int*)a, 0, 16);
23  return NULL;
24}
25
26int main() {
27  pthread_t t[2];
28  // Race on x between memcpy and memset
29  pthread_create(&t[0], NULL, MemCpyThread, x);
30  pthread_create(&t[1], NULL, MemSetThread, x);
31  pthread_join(t[0], NULL);
32  pthread_join(t[1], NULL);
33  // Race on y between memmove and memset
34  pthread_create(&t[0], NULL, MemMoveThread, y);
35  pthread_create(&t[1], NULL, MemSetThread, y);
36  pthread_join(t[0], NULL);
37  pthread_join(t[1], NULL);
38
39  printf("PASS\n");
40  return 0;
41}
42
43// CHECK: WARNING: ThreadSanitizer: data race
44// CHECK:   #0 memset
45// CHECK:   #1 MemSetThread
46// CHECK:  Previous write
47// CHECK:   #0 memcpy
48// CHECK:   #1 MemCpyThread
49
50// CHECK: WARNING: ThreadSanitizer: data race
51// CHECK:   #0 memset
52// CHECK:   #1 MemSetThread
53// CHECK:  Previous write
54// CHECK:   #0 memmove
55// CHECK:   #1 MemMoveThread
56