clang 22.0.0git
ThreadSafety.h
Go to the documentation of this file.
1//===- ThreadSafety.h -------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9//
10// A intra-procedural analysis for thread safety (e.g. deadlocks and race
11// conditions), based off of an annotation system.
12//
13// See http://clang.llvm.org/docs/LanguageExtensions.html#thread-safety-annotation-checking
14// for more information.
15//
16//===----------------------------------------------------------------------===//
17
18#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
19#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
20
22#include "llvm/ADT/StringRef.h"
23
24namespace clang {
25
26class AnalysisDeclContext;
27class FunctionDecl;
28class NamedDecl;
29
30namespace threadSafety {
31
32class BeforeSet;
33
34/// This enum distinguishes between different kinds of operations that may
35/// need to be protected by locks. We use this enum in error handling.
37 /// Dereferencing a variable (e.g. p in *p = 5;)
39
40 /// Reading or writing a variable (e.g. x in x = 5;)
42
43 /// Making a function call (e.g. fool())
45
46 /// Passing a guarded variable by reference.
48
49 /// Passing a pt-guarded variable by reference.
51
52 /// Returning a guarded variable by reference.
54
55 /// Returning a pt-guarded variable by reference.
57
58 /// Passing pointer to a guarded variable.
60
61 /// Passing a pt-guarded pointer.
63
64 /// Returning pointer to a guarded variable.
66
67 /// Returning a pt-guarded pointer.
69};
70
71/// This enum distinguishes between different kinds of lock actions. For
72/// example, it is an error to write a variable protected by shared version of a
73/// mutex.
75 /// Shared/reader lock of a mutex.
77
78 /// Exclusive/writer lock of a mutex.
80
81 /// Can be either Shared or Exclusive.
83};
84
85/// This enum distinguishes between different ways to access (read or write) a
86/// variable.
88 /// Reading a variable.
90
91 /// Writing a variable.
93};
94
95/// This enum distinguishes between different situations where we warn due to
96/// inconsistent locking.
98 /// A capability is locked for some but not all loop iterations.
100 /// A capability is locked in some but not all predecessors of a CFGBlock.
102 /// A capability is still locked at the end of a function.
104 /// Expecting a capability to be held at the end of function.
107
108/// Handler class for thread safety warnings.
110public:
111 using Name = StringRef;
112
115
116 /// Warn about lock expressions which fail to resolve to lockable objects.
117 /// \param Loc -- the SourceLocation of the unresolved expression.
119
120 /// Warn about unlock function calls that do not have a prior matching lock
121 /// expression.
122 /// \param Kind -- the capability's name parameter (role, mutex, etc).
123 /// \param LockName -- A StringRef name for the lock expression, to be printed
124 /// in the error message.
125 /// \param Loc -- The SourceLocation of the Unlock
126 /// \param LocPreviousUnlock -- If valid, the location of a previous Unlock.
127 virtual void handleUnmatchedUnlock(StringRef Kind, Name LockName,
129 SourceLocation LocPreviousUnlock) {}
130
131 /// Warn about an unlock function call that attempts to unlock a lock with
132 /// the incorrect lock kind. For instance, a shared lock being unlocked
133 /// exclusively, or vice versa.
134 /// \param LockName -- A StringRef name for the lock expression, to be printed
135 /// in the error message.
136 /// \param Kind -- the capability's name parameter (role, mutex, etc).
137 /// \param Expected -- the kind of lock expected.
138 /// \param Received -- the kind of lock received.
139 /// \param LocLocked -- The SourceLocation of the Lock.
140 /// \param LocUnlock -- The SourceLocation of the Unlock.
141 virtual void handleIncorrectUnlockKind(StringRef Kind, Name LockName,
142 LockKind Expected, LockKind Received,
143 SourceLocation LocLocked,
144 SourceLocation LocUnlock) {}
145
146 /// Warn about lock function calls for locks which are already held.
147 /// \param Kind -- the capability's name parameter (role, mutex, etc).
148 /// \param LockName -- A StringRef name for the lock expression, to be printed
149 /// in the error message.
150 /// \param LocLocked -- The location of the first lock expression.
151 /// \param LocDoubleLock -- The location of the second lock expression.
152 virtual void handleDoubleLock(StringRef Kind, Name LockName,
153 SourceLocation LocLocked,
154 SourceLocation LocDoubleLock) {}
155
156 /// Warn about situations where a mutex is sometimes held and sometimes not.
157 /// The three situations are:
158 /// 1. a mutex is locked on an "if" branch but not the "else" branch,
159 /// 2, or a mutex is only held at the start of some loop iterations,
160 /// 3. or when a mutex is locked but not unlocked inside a function.
161 /// \param Kind -- the capability's name parameter (role, mutex, etc).
162 /// \param LockName -- A StringRef name for the lock expression, to be printed
163 /// in the error message.
164 /// \param LocLocked -- The location of the lock expression where the mutex is
165 /// locked
166 /// \param LocEndOfScope -- The location of the end of the scope where the
167 /// mutex is no longer held
168 /// \param LEK -- which of the three above cases we should warn for
169 /// \param ReentrancyMismatch -- mismatching reentrancy depth
170 virtual void handleMutexHeldEndOfScope(StringRef Kind, Name LockName,
171 SourceLocation LocLocked,
172 SourceLocation LocEndOfScope,
173 LockErrorKind LEK,
174 bool ReentrancyMismatch = false) {}
175
176 /// Warn when a mutex is held exclusively and shared at the same point. For
177 /// example, if a mutex is locked exclusively during an if branch and shared
178 /// during the else branch.
179 /// \param Kind -- the capability's name parameter (role, mutex, etc).
180 /// \param LockName -- A StringRef name for the lock expression, to be printed
181 /// in the error message.
182 /// \param Loc1 -- The location of the first lock expression.
183 /// \param Loc2 -- The location of the second lock expression.
184 virtual void handleExclusiveAndShared(StringRef Kind, Name LockName,
185 SourceLocation Loc1,
186 SourceLocation Loc2) {}
187
188 /// Warn when a protected operation occurs while no locks are held.
189 /// \param D -- The decl for the protected variable or function
190 /// \param POK -- The kind of protected operation (e.g. variable access)
191 /// \param AK -- The kind of access (i.e. read or write) that occurred
192 /// \param Loc -- The location of the protected operation.
195
196 /// Warn when a protected operation occurs while the specific mutex protecting
197 /// the operation is not locked.
198 /// \param Kind -- the capability's name parameter (role, mutex, etc).
199 /// \param D -- The decl for the protected variable or function
200 /// \param POK -- The kind of protected operation (e.g. variable access)
201 /// \param LockName -- A StringRef name for the lock expression, to be printed
202 /// in the error message.
203 /// \param LK -- The kind of access (i.e. read or write) that occurred
204 /// \param Loc -- The location of the protected operation.
205 virtual void handleMutexNotHeld(StringRef Kind, const NamedDecl *D,
206 ProtectedOperationKind POK, Name LockName,
208 Name *PossibleMatch = nullptr) {}
209
210 /// Warn when acquiring a lock that the negative capability is not held.
211 /// \param Kind -- the capability's name parameter (role, mutex, etc).
212 /// \param LockName -- The name for the lock expression, to be printed in the
213 /// diagnostic.
214 /// \param Neg -- The name of the negative capability to be printed in the
215 /// diagnostic.
216 /// \param Loc -- The location of the protected operation.
217 virtual void handleNegativeNotHeld(StringRef Kind, Name LockName, Name Neg,
219
220 /// Warn when calling a function that a negative capability is not held.
221 /// \param D -- The decl for the function requiring the negative capability.
222 /// \param LockName -- The name for the lock expression, to be printed in the
223 /// diagnostic.
224 /// \param Loc -- The location of the protected operation.
225 virtual void handleNegativeNotHeld(const NamedDecl *D, Name LockName,
227
228 /// Warn when a function is called while an excluded mutex is locked. For
229 /// example, the mutex may be locked inside the function.
230 /// \param Kind -- the capability's name parameter (role, mutex, etc).
231 /// \param FunName -- The name of the function
232 /// \param LockName -- A StringRef name for the lock expression, to be printed
233 /// in the error message.
234 /// \param Loc -- The location of the function call.
235 virtual void handleFunExcludesLock(StringRef Kind, Name FunName,
236 Name LockName, SourceLocation Loc) {}
237
238 /// Warn when an actual underlying mutex of a scoped lockable does not match
239 /// the expected.
240 /// \param Loc -- The location of the call expression.
241 /// \param DLoc -- The location of the function declaration.
242 /// \param ScopeName -- The name of the scope passed to the function.
243 /// \param Kind -- The kind of the expected mutex.
244 /// \param Expected -- The name of the expected mutex.
245 /// \param Actual -- The name of the actual mutex.
247 SourceLocation DLoc,
248 Name ScopeName, StringRef Kind,
249 Name Expected, Name Actual) {}
250
251 /// Warn when we get fewer underlying mutexes than expected.
252 /// \param Loc -- The location of the call expression.
253 /// \param DLoc -- The location of the function declaration.
254 /// \param ScopeName -- The name of the scope passed to the function.
255 /// \param Kind -- The kind of the expected mutex.
256 /// \param Expected -- The name of the expected mutex.
258 SourceLocation DLoc,
259 Name ScopeName, StringRef Kind,
260 Name Expected) {}
261
262 /// Warn when we get more underlying mutexes than expected.
263 /// \param Loc -- The location of the call expression.
264 /// \param DLoc -- The location of the function declaration.
265 /// \param ScopeName -- The name of the scope passed to the function.
266 /// \param Kind -- The kind of the actual mutex.
267 /// \param Actual -- The name of the actual mutex.
269 SourceLocation DLoc,
270 Name ScopeName,
271 StringRef Kind, Name Actual) {
272 }
273
274 /// Warn that L1 cannot be acquired before L2.
275 virtual void handleLockAcquiredBefore(StringRef Kind, Name L1Name,
276 Name L2Name, SourceLocation Loc) {}
277
278 /// Warn that there is a cycle in acquired_before/after dependencies.
280
281 /// Called by the analysis when starting analysis of a function.
282 /// Used to issue suggestions for changes to annotations.
283 virtual void enterFunction(const FunctionDecl *FD) {}
284
285 /// Called by the analysis when finishing analysis of a function.
286 virtual void leaveFunction(const FunctionDecl *FD) {}
287
288 bool issueBetaWarnings() { return IssueBetaWarnings; }
289 void setIssueBetaWarnings(bool b) { IssueBetaWarnings = b; }
290
291private:
292 bool IssueBetaWarnings = false;
293};
294
295/// Check a function's CFG for thread-safety violations.
296///
297/// We traverse the blocks in the CFG, compute the set of mutexes that are held
298/// at the end of each block, and issue warnings for thread safety violations.
299/// Each block in the CFG is traversed exactly once.
301 ThreadSafetyHandler &Handler,
302 BeforeSet **Bset);
303
304void threadSafetyCleanup(BeforeSet *Cache);
305
306/// Helper function that returns a LockKind required for the given level
307/// of access.
309
310} // namespace threadSafety
311} // namespace clang
312
313#endif // LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
const Decl * D
enum clang::sema::@1840::IndirectLocalPathEntry::EntryKind Kind
SourceLocation Loc
Definition: SemaObjC.cpp:754
Defines the clang::SourceLocation class and associated facilities.
TypePropertyCache< Private > Cache
Definition: Type.cpp:4836
__device__ __2f16 b
AnalysisDeclContext contains the context data for the function, method or block under analysis.
Represents a function declaration or definition.
Definition: Decl.h:1999
This represents a decl that may have a name.
Definition: Decl.h:273
Encodes a location in the source.
Handler class for thread safety warnings.
Definition: ThreadSafety.h:109
virtual void handleBeforeAfterCycle(Name L1Name, SourceLocation Loc)
Warn that there is a cycle in acquired_before/after dependencies.
Definition: ThreadSafety.h:279
virtual void handleExpectMoreUnderlyingMutexes(SourceLocation Loc, SourceLocation DLoc, Name ScopeName, StringRef Kind, Name Expected)
Warn when we get fewer underlying mutexes than expected.
Definition: ThreadSafety.h:257
virtual void handleInvalidLockExp(SourceLocation Loc)
Warn about lock expressions which fail to resolve to lockable objects.
Definition: ThreadSafety.h:118
virtual void handleUnmatchedUnderlyingMutexes(SourceLocation Loc, SourceLocation DLoc, Name ScopeName, StringRef Kind, Name Expected, Name Actual)
Warn when an actual underlying mutex of a scoped lockable does not match the expected.
Definition: ThreadSafety.h:246
virtual void handleExpectFewerUnderlyingMutexes(SourceLocation Loc, SourceLocation DLoc, Name ScopeName, StringRef Kind, Name Actual)
Warn when we get more underlying mutexes than expected.
Definition: ThreadSafety.h:268
virtual void enterFunction(const FunctionDecl *FD)
Called by the analysis when starting analysis of a function.
Definition: ThreadSafety.h:283
virtual void handleIncorrectUnlockKind(StringRef Kind, Name LockName, LockKind Expected, LockKind Received, SourceLocation LocLocked, SourceLocation LocUnlock)
Warn about an unlock function call that attempts to unlock a lock with the incorrect lock kind.
Definition: ThreadSafety.h:141
virtual void handleMutexHeldEndOfScope(StringRef Kind, Name LockName, SourceLocation LocLocked, SourceLocation LocEndOfScope, LockErrorKind LEK, bool ReentrancyMismatch=false)
Warn about situations where a mutex is sometimes held and sometimes not.
Definition: ThreadSafety.h:170
virtual void leaveFunction(const FunctionDecl *FD)
Called by the analysis when finishing analysis of a function.
Definition: ThreadSafety.h:286
virtual void handleExclusiveAndShared(StringRef Kind, Name LockName, SourceLocation Loc1, SourceLocation Loc2)
Warn when a mutex is held exclusively and shared at the same point.
Definition: ThreadSafety.h:184
virtual void handleLockAcquiredBefore(StringRef Kind, Name L1Name, Name L2Name, SourceLocation Loc)
Warn that L1 cannot be acquired before L2.
Definition: ThreadSafety.h:275
virtual void handleMutexNotHeld(StringRef Kind, const NamedDecl *D, ProtectedOperationKind POK, Name LockName, LockKind LK, SourceLocation Loc, Name *PossibleMatch=nullptr)
Warn when a protected operation occurs while the specific mutex protecting the operation is not locke...
Definition: ThreadSafety.h:205
virtual void handleFunExcludesLock(StringRef Kind, Name FunName, Name LockName, SourceLocation Loc)
Warn when a function is called while an excluded mutex is locked.
Definition: ThreadSafety.h:235
virtual void handleNoMutexHeld(const NamedDecl *D, ProtectedOperationKind POK, AccessKind AK, SourceLocation Loc)
Warn when a protected operation occurs while no locks are held.
Definition: ThreadSafety.h:193
virtual void handleNegativeNotHeld(const NamedDecl *D, Name LockName, SourceLocation Loc)
Warn when calling a function that a negative capability is not held.
Definition: ThreadSafety.h:225
virtual void handleUnmatchedUnlock(StringRef Kind, Name LockName, SourceLocation Loc, SourceLocation LocPreviousUnlock)
Warn about unlock function calls that do not have a prior matching lock expression.
Definition: ThreadSafety.h:127
virtual void handleNegativeNotHeld(StringRef Kind, Name LockName, Name Neg, SourceLocation Loc)
Warn when acquiring a lock that the negative capability is not held.
Definition: ThreadSafety.h:217
virtual void handleDoubleLock(StringRef Kind, Name LockName, SourceLocation LocLocked, SourceLocation LocDoubleLock)
Warn about lock function calls for locks which are already held.
Definition: ThreadSafety.h:152
LockKind getLockKindFromAccessKind(AccessKind AK)
Helper function that returns a LockKind required for the given level of access.
LockErrorKind
This enum distinguishes between different situations where we warn due to inconsistent locking.
Definition: ThreadSafety.h:97
@ LEK_NotLockedAtEndOfFunction
Expecting a capability to be held at the end of function.
Definition: ThreadSafety.h:105
@ LEK_LockedSomePredecessors
A capability is locked in some but not all predecessors of a CFGBlock.
Definition: ThreadSafety.h:101
@ LEK_LockedAtEndOfFunction
A capability is still locked at the end of a function.
Definition: ThreadSafety.h:103
@ LEK_LockedSomeLoopIterations
A capability is locked for some but not all loop iterations.
Definition: ThreadSafety.h:99
void threadSafetyCleanup(BeforeSet *Cache)
AccessKind
This enum distinguishes between different ways to access (read or write) a variable.
Definition: ThreadSafety.h:87
@ AK_Written
Writing a variable.
Definition: ThreadSafety.h:92
@ AK_Read
Reading a variable.
Definition: ThreadSafety.h:89
LockKind
This enum distinguishes between different kinds of lock actions.
Definition: ThreadSafety.h:74
@ LK_Shared
Shared/reader lock of a mutex.
Definition: ThreadSafety.h:76
@ LK_Exclusive
Exclusive/writer lock of a mutex.
Definition: ThreadSafety.h:79
@ LK_Generic
Can be either Shared or Exclusive.
Definition: ThreadSafety.h:82
void runThreadSafetyAnalysis(AnalysisDeclContext &AC, ThreadSafetyHandler &Handler, BeforeSet **Bset)
Check a function's CFG for thread-safety violations.
ProtectedOperationKind
This enum distinguishes between different kinds of operations that may need to be protected by locks.
Definition: ThreadSafety.h:36
@ POK_PtPassByRef
Passing a pt-guarded variable by reference.
Definition: ThreadSafety.h:50
@ POK_PassPointer
Passing pointer to a guarded variable.
Definition: ThreadSafety.h:59
@ POK_VarDereference
Dereferencing a variable (e.g. p in *p = 5;)
Definition: ThreadSafety.h:38
@ POK_PassByRef
Passing a guarded variable by reference.
Definition: ThreadSafety.h:47
@ POK_ReturnByRef
Returning a guarded variable by reference.
Definition: ThreadSafety.h:53
@ POK_PtPassPointer
Passing a pt-guarded pointer.
Definition: ThreadSafety.h:62
@ POK_PtReturnPointer
Returning a pt-guarded pointer.
Definition: ThreadSafety.h:68
@ POK_VarAccess
Reading or writing a variable (e.g. x in x = 5;)
Definition: ThreadSafety.h:41
@ POK_FunctionCall
Making a function call (e.g. fool())
Definition: ThreadSafety.h:44
@ POK_ReturnPointer
Returning pointer to a guarded variable.
Definition: ThreadSafety.h:65
@ POK_PtReturnByRef
Returning a pt-guarded variable by reference.
Definition: ThreadSafety.h:56
The JSON file list parser is used to communicate input to InstallAPI.