1// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
2#include <pthread.h>
3#include <semaphore.h>
4#include <stdio.h>
5#include <unistd.h>
6
7struct A {
8  A() {
9    sem_init(&sem_, 0, 0);
10  }
11  virtual void F() {
12  }
13  void Done() {
14    sem_post(&sem_);
15  }
16  virtual ~A() {
17    sem_wait(&sem_);
18    sem_destroy(&sem_);
19  }
20  sem_t sem_;
21};
22
23struct B : A {
24  virtual void F() {
25  }
26  virtual ~B() { }
27};
28
29static A *obj = new B;
30static void (A::*fn)() = &A::F;
31
32void *Thread1(void *x) {
33  sleep(1);
34  (obj->*fn)();
35  obj->Done();
36  return NULL;
37}
38
39void *Thread2(void *x) {
40  delete obj;
41  return NULL;
42}
43
44int main() {
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