1 // RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t 2>&1 | FileCheck %s
2 
3 #include <pthread.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <setjmp.h>
7 
bar(jmp_buf env)8 void bar(jmp_buf env) {
9   volatile int x = 42;
10   longjmp(env, 42);
11   x++;
12 }
13 
foo(jmp_buf env)14 void foo(jmp_buf env) {
15   volatile int x = 42;
16   bar(env);
17   x++;
18 }
19 
badguy()20 void badguy() __attribute__((noinline)) {
21   pthread_mutex_t mtx;
22   pthread_mutex_init(&mtx, 0);
23   pthread_mutex_lock(&mtx);
24   pthread_mutex_destroy(&mtx);
25 }
26 
mymain()27 void mymain() __attribute__((noinline)) {
28   jmp_buf env;
29   if (setjmp(env) == 42) {
30     badguy();
31     return;
32   }
33   foo(env);
34   fprintf(stderr, "FAILED\n");
35 }
36 
main()37 int main() {
38   volatile int x = 42;
39   mymain();
40   return x;
41 }
42 
43 // CHECK-NOT: FAILED
44 // CHECK: WARNING: ThreadSanitizer: destroy of a locked mutex
45 // CHECK:   #0 pthread_mutex_destroy
46 // CHECK:   #1 badguy
47 // CHECK:   #2 mymain
48 // CHECK:   #3 main
49 
50