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