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