1// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
2#include "test.h"
3#include <semaphore.h>
4
5struct A {
6  A() {
7    sem_init(&sem_, 0, 0);
8  }
9  virtual void F() {
10  }
11  void Done() {
12    sem_post(&sem_);
13  }
14  virtual ~A() {
15    sem_wait(&sem_);
16    sem_destroy(&sem_);
17  }
18  sem_t sem_;
19};
20
21struct B : A {
22  virtual void F() {
23  }
24  virtual ~B() { }
25};
26
27static A *obj = new B;
28static void (A::*fn)() = &A::F;
29
30void *Thread1(void *x) {
31  (obj->*fn)();
32  barrier_wait(&barrier);
33  obj->Done();
34  return NULL;
35}
36
37void *Thread2(void *x) {
38  barrier_wait(&barrier);
39  delete obj;
40  return NULL;
41}
42
43int main() {
44  barrier_init(&barrier, 2);
45  pthread_t t[2];
46  pthread_create(&t[0], NULL, Thread1, NULL);
47  pthread_create(&t[1], NULL, Thread2, NULL);
48  pthread_join(t[0], NULL);
49  pthread_join(t[1], NULL);
50}
51
52// CHECK: WARNING: ThreadSanitizer: data race on vptr
53
54