1// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
2#include <pthread.h>
3#include <stdio.h>
4
5struct A {
6  A() {
7    pthread_mutex_init(&m, 0);
8    pthread_cond_init(&c, 0);
9    signaled = false;
10  }
11  virtual void F() {
12  }
13  void Done() {
14    pthread_mutex_lock(&m);
15    signaled = true;
16    pthread_cond_signal(&c);
17    pthread_mutex_unlock(&m);
18  }
19  virtual ~A() {
20  }
21  pthread_mutex_t m;
22  pthread_cond_t c;
23  bool signaled;
24};
25
26struct B : A {
27  virtual void F() {
28  }
29  virtual ~B() {
30    pthread_mutex_lock(&m);
31    while (!signaled)
32      pthread_cond_wait(&c, &m);
33    pthread_mutex_unlock(&m);
34  }
35};
36
37static A *obj = new B;
38
39void *Thread1(void *x) {
40  obj->F();
41  obj->Done();
42  return NULL;
43}
44
45void *Thread2(void *x) {
46  delete obj;
47  return NULL;
48}
49
50int main() {
51  pthread_t t[2];
52  pthread_create(&t[0], NULL, Thread1, NULL);
53  pthread_create(&t[1], NULL, Thread2, NULL);
54  pthread_join(t[0], NULL);
55  pthread_join(t[1], NULL);
56  fprintf(stderr, "PASS\n");
57}
58// CHECK: PASS
59// CHECK-NOT: WARNING: ThreadSanitizer: data race
60