1c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t 2>&1 | FileCheck %s
2cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
3cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar// Longjmp assembly has not been implemented for mips64 yet
4cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar// XFAIL: mips64
5cdce50bda3603770cc4ef80cbb613c78b8e47a17Pirama Arumuga Nainar
68b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov#include <pthread.h>
78b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov#include <stdio.h>
88b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov#include <stdlib.h>
98b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov#include <setjmp.h>
108b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov
118b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukovvoid bar(jmp_buf env) {
128b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov  volatile int x = 42;
138b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov  longjmp(env, 42);
148b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov  x++;
158b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov}
168b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov
178b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukovvoid foo(jmp_buf env) {
188b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov  volatile int x = 42;
198b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov  bar(env);
208b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov  x++;
218b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov}
228b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov
238b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukovvoid badguy() {
248b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov  pthread_mutex_t mtx;
258b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov  pthread_mutex_init(&mtx, 0);
268b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov  pthread_mutex_lock(&mtx);
278b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov  pthread_mutex_destroy(&mtx);
288b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov}
298b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov
308b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukovvoid mymain() {
318b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov  jmp_buf env;
328b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov  if (setjmp(env) == 42) {
338b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov    badguy();
348b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov    return;
358b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov  }
368b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov  foo(env);
37c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  fprintf(stderr, "FAILED\n");
388b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov}
398b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov
408b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukovint main() {
418b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov  volatile int x = 42;
428b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov  mymain();
438b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov  return x;
448b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov}
458b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov
468b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov// CHECK-NOT: FAILED
478b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov// CHECK: WARNING: ThreadSanitizer: destroy of a locked mutex
488b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov// CHECK:   #0 pthread_mutex_destroy
498b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov// CHECK:   #1 badguy
508b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov// CHECK:   #2 mymain
518b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov// CHECK:   #3 main
528b30c254a63a7421dd81d13dee086a54c4ca134bDmitry Vyukov
53