Index: lib/Analysis/ThreadSafety.cpp =================================================================== --- lib/Analysis/ThreadSafety.cpp +++ lib/Analysis/ThreadSafety.cpp @@ -1450,6 +1450,14 @@ // If the condition is a call to a Trylock function, then grab the attributes for (const auto *Attr : FunDecl->attrs()) { switch (Attr->getKind()) { + case attr::TryAcquireCapability: { + auto *A = cast(Attr); + getMutexIDs(A->isShared() ? SharedLocksToAdd : ExclusiveLocksToAdd, A, + Exp, FunDecl, PredBlock, CurrBlock, A->getSuccessValue(), + Negate); + CapDiagKind = ClassifyDiagnostic(A); + break; + }; case attr::ExclusiveTrylockFunction: { const auto *A = cast(Attr); getMutexIDs(ExclusiveLocksToAdd, A, Exp, FunDecl, @@ -2249,10 +2257,13 @@ A, nullptr, D); CapDiagKind = ClassifyDiagnostic(A); } else if (isa(Attr)) { - // Don't try to check trylock functions for now + // Don't try to check trylock functions for now. return; } else if (isa(Attr)) { - // Don't try to check trylock functions for now + // Don't try to check trylock functions for now. + return; + } else if (isa(Attr)) { + // Don't try to check trylock functions for now. return; } } Index: test/SemaCXX/warn-thread-safety-analysis.cpp =================================================================== --- test/SemaCXX/warn-thread-safety-analysis.cpp +++ test/SemaCXX/warn-thread-safety-analysis.cpp @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_ASSERT_CAPABILITY=0 %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_ASSERT_CAPABILITY=1 %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_ASSERT_CAPABILITY=0 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_ASSERT_CAPABILITY=1 -DUSE_TRY_ACQUIRE_CAPABILITY %s // FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 -Wc++98-compat %s // FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety %s @@ -24,8 +25,13 @@ #define ASSERT_SHARED_LOCK(...) __attribute__((assert_shared_lock(__VA_ARGS__))) #endif +#ifdef USE_TRY_ACQUIRE_CAPABILITY +#define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__((try_acquire_capability(__VA_ARGS__))) +#define SHARED_TRYLOCK_FUNCTION(...) __attribute__((try_acquire_shared_capability(__VA_ARGS__))) +#else #define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__((exclusive_trylock_function(__VA_ARGS__))) #define SHARED_TRYLOCK_FUNCTION(...) __attribute__((shared_trylock_function(__VA_ARGS__))) +#endif #define UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__))) #define EXCLUSIVE_UNLOCK_FUNCTION(...) __attribute__((release_capability(__VA_ARGS__))) #define SHARED_UNLOCK_FUNCTION(...) __attribute__((release_shared_capability(__VA_ARGS__))) @@ -41,8 +47,8 @@ void Lock() __attribute__((exclusive_lock_function)); void ReaderLock() __attribute__((shared_lock_function)); void Unlock() __attribute__((unlock_function)); - bool TryLock() __attribute__((exclusive_trylock_function(true))); - bool ReaderTryLock() __attribute__((shared_trylock_function(true))); + bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true); + bool ReaderTryLock() SHARED_TRYLOCK_FUNCTION(true); void LockWhen(const int &cond) __attribute__((exclusive_lock_function)); // for negative capabilities