1 // RUN: %clangxx_tsan -O1 --std=c++11 %s -o %t && %run %t 2>&1 | FileCheck %s 2 #include "custom_mutex.h" 3 4 #include <type_traits> 5 6 // Test that the destruction events of a mutex are ignored when the 7 // annotations request this. 8 // 9 // Use after destruction is UB, but __tsan_mutex_linker_init and 10 // __tsan_mutex_not_static exist to support global variables of mutex type, 11 // which might be accessed during program shutdown after the class's destructor 12 // has run. 13 main()14int main() { 15 std::aligned_storage<sizeof(Mutex), alignof(Mutex)>::type mu1_store; 16 Mutex* mu1 = reinterpret_cast<Mutex*>(&mu1_store); 17 new(&mu1_store) Mutex(false, __tsan_mutex_linker_init); 18 mu1->Lock(); 19 mu1->~Mutex(); 20 mu1->Unlock(); 21 22 std::aligned_storage<sizeof(Mutex), alignof(Mutex)>::type mu2_store; 23 Mutex* mu2 = reinterpret_cast<Mutex*>(&mu2_store); 24 new(&mu2_store) Mutex(false, 0, __tsan_mutex_not_static); 25 mu2->Lock(); 26 mu2->~Mutex(); 27 mu2->Unlock(); 28 29 fprintf(stderr, "DONE\n"); 30 return 0; 31 } 32 33 // CHECK: DONE 34