Skip to content

Commit ab1dc2d

Browse files
committed
Thread Safety Analysis: add support for before/after annotations on mutexes.
These checks detect potential deadlocks caused by inconsistent lock ordering. The checks are implemented under the -Wthread-safety-beta flag. This patch also replaces calls to getAttrs() with calls to attrs() throughout ThreadSafety.cpp, which fixes the earlier issue that cause assert failures. llvm-svn: 228051
1 parent e4101e2 commit ab1dc2d

File tree

8 files changed

+486
-28
lines changed

8 files changed

+486
-28
lines changed

clang/include/clang/Analysis/Analyses/ThreadSafety.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
namespace clang {
2727
namespace threadSafety {
2828

29+
class BeforeSet;
30+
2931
/// This enum distinguishes between different kinds of operations that may
3032
/// need to be protected by locks. We use this enum in error handling.
3133
enum ProtectedOperationKind {
@@ -183,6 +185,14 @@ class ThreadSafetyHandler {
183185
virtual void handleFunExcludesLock(StringRef Kind, Name FunName,
184186
Name LockName, SourceLocation Loc) {}
185187

188+
189+
/// Warn that L1 cannot be acquired before L2.
190+
virtual void handleLockAcquiredBefore(StringRef Kind, Name L1Name,
191+
Name L2Name, SourceLocation Loc) {}
192+
193+
/// Warn that there is a cycle in acquired_before/after dependencies.
194+
virtual void handleBeforeAfterCycle(Name L1Name, SourceLocation Loc) {}
195+
186196
/// Called by the analysis when starting analysis of a function.
187197
/// Used to issue suggestions for changes to annotations.
188198
virtual void enterFunction(const FunctionDecl *FD) {}
@@ -203,7 +213,8 @@ class ThreadSafetyHandler {
203213
/// at the end of each block, and issue warnings for thread safety violations.
204214
/// Each block in the CFG is traversed exactly once.
205215
void runThreadSafetyAnalysis(AnalysisDeclContext &AC,
206-
ThreadSafetyHandler &Handler);
216+
ThreadSafetyHandler &Handler,
217+
BeforeSet **Bset);
207218

208219
/// \brief Helper function that returns a LockKind required for the given level
209220
/// of access.

clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,14 @@ class CapabilityExpr {
286286
sx::partiallyMatches(CapExpr, other.CapExpr);
287287
}
288288

289+
const ValueDecl* valueDecl() const {
290+
if (Negated)
291+
return nullptr;
292+
if (auto *P = dyn_cast<til::Project>(CapExpr))
293+
return P->clangDecl();
294+
return nullptr;
295+
}
296+
289297
std::string toString() const {
290298
if (Negated)
291299
return "!" + sx::toString(CapExpr);

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2394,6 +2394,13 @@ def warn_fun_excludes_mutex : Warning<
23942394
def warn_cannot_resolve_lock : Warning<
23952395
"cannot resolve lock expression">,
23962396
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
2397+
def warn_acquired_before : Warning<
2398+
"%0 '%1' must be acquired before '%2'">,
2399+
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
2400+
def warn_acquired_before_after_cycle : Warning<
2401+
"Cycle in acquired_before/after dependencies, starting with '%0'">,
2402+
InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
2403+
23972404

23982405
// Thread safety warnings negative capabilities
23992406
def warn_acquire_requires_negative_cap : Warning<

clang/include/clang/Sema/Sema.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,11 @@ namespace sema {
199199
class TemplateDeductionInfo;
200200
}
201201

202+
namespace threadSafety {
203+
class BeforeSet;
204+
void threadSafetyCleanup(BeforeSet* Cache);
205+
}
206+
202207
// FIXME: No way to easily map from TemplateTypeParmTypes to
203208
// TemplateTypeParmDecls, so we have this horrible PointerUnion.
204209
typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType*, NamedDecl*>,
@@ -6708,6 +6713,7 @@ class Sema {
67086713

67096714
/// \brief Worker object for performing CFG-based warnings.
67106715
sema::AnalysisBasedWarnings AnalysisWarnings;
6716+
threadSafety::BeforeSet *ThreadSafetyDeclCache;
67116717

67126718
/// \brief An entity for which implicit template instantiation is required.
67136719
///

0 commit comments

Comments
 (0)