From bbed8cfe80cd27d3a47d877c7608d9be4e487d97 Mon Sep 17 00:00:00 2001 From: Aaron Puchert Date: Fri, 30 Oct 2020 00:35:14 +0100 Subject: [PATCH] Thread safety analysis: Consider static class members as inaccessible This fixes the issue pointed out in D84604#2363134. For now we exclude static members completely, we'll take them into account later. --- clang/lib/Analysis/ThreadSafety.cpp | 10 +++++-- .../SemaCXX/warn-thread-safety-negative.cpp | 27 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp index 65d410a65ba4..21583e92c72d 100644 --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -1269,10 +1269,16 @@ bool ThreadSafetyAnalyzer::inCurrentScope(const CapabilityExpr &CapE) { const threadSafety::til::SExpr *SExp = CapE.sexpr(); assert(SExp && "Null expressions should be ignored"); - // Global variables are always in scope. if (const auto *LP = dyn_cast(SExp)) { const ValueDecl *VD = LP->clangDecl(); - return VD->isDefinedOutsideFunctionOrMethod(); + // Variables defined in a function are always inaccessible. + if (!VD->isDefinedOutsideFunctionOrMethod()) + return false; + // For now we consider static class members to be inaccessible. + if (isa(VD->getDeclContext())) + return false; + // Global variables are always in scope. + return true; } // Members are in scope from methods of the same class. diff --git a/clang/test/SemaCXX/warn-thread-safety-negative.cpp b/clang/test/SemaCXX/warn-thread-safety-negative.cpp index d7db5f402d11..9eabd67e4fc7 100644 --- a/clang/test/SemaCXX/warn-thread-safety-negative.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-negative.cpp @@ -118,6 +118,33 @@ void testNamespaceGlobals() EXCLUSIVE_LOCKS_REQUIRED(!globalMutex) { ns::fq(); // expected-warning {{calling function 'fq' requires negative capability '!globalMutex'}} } +class StaticMembers { +public: + void pub() EXCLUSIVE_LOCKS_REQUIRED(!publicMutex); + void prot() EXCLUSIVE_LOCKS_REQUIRED(!protectedMutex); + void priv() EXCLUSIVE_LOCKS_REQUIRED(!privateMutex); + void test() { + pub(); + prot(); + priv(); + } + + static Mutex publicMutex; + +protected: + static Mutex protectedMutex; + +private: + static Mutex privateMutex; +}; + +void testStaticMembers() { + StaticMembers x; + x.pub(); + x.prot(); + x.priv(); +} + } // end namespace ScopeTest namespace DoubleAttribute {