]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ThreadSafety.h
Merge clang trunk r321017 to contrib/llvm/tools/clang.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / Analysis / Analyses / ThreadSafety.h
1 //===- ThreadSafety.h ------------------------------------------*- C++ --*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //
11 // A intra-procedural analysis for thread safety (e.g. deadlocks and race
12 // conditions), based off of an annotation system.
13 //
14 // See http://clang.llvm.org/docs/LanguageExtensions.html#thread-safety-annotation-checking
15 // for more information.
16 //
17 //===----------------------------------------------------------------------===//
18
19 #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
20 #define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
21
22 #include "clang/Analysis/AnalysisDeclContext.h"
23 #include "clang/Basic/SourceLocation.h"
24 #include "llvm/ADT/StringRef.h"
25
26 namespace clang {
27 namespace threadSafety {
28
29 class BeforeSet;
30
31 /// This enum distinguishes between different kinds of operations that may
32 /// need to be protected by locks. We use this enum in error handling.
33 enum ProtectedOperationKind {
34   POK_VarDereference, ///< Dereferencing a variable (e.g. p in *p = 5;)
35   POK_VarAccess, ///< Reading or writing a variable (e.g. x in x = 5;)
36   POK_FunctionCall, ///< Making a function call (e.g. fool())
37   POK_PassByRef, ///< Passing a guarded variable by reference.
38   POK_PtPassByRef,  ///< Passing a pt-guarded variable by reference.
39 };
40
41 /// This enum distinguishes between different kinds of lock actions. For
42 /// example, it is an error to write a variable protected by shared version of a
43 /// mutex.
44 enum LockKind {
45   LK_Shared,    ///< Shared/reader lock of a mutex.
46   LK_Exclusive, ///< Exclusive/writer lock of a mutex.
47   LK_Generic    ///< Can be either Shared or Exclusive
48 };
49
50 /// This enum distinguishes between different ways to access (read or write) a
51 /// variable.
52 enum AccessKind {
53   AK_Read, ///< Reading a variable.
54   AK_Written ///< Writing a variable.
55 };
56
57 /// This enum distinguishes between different situations where we warn due to
58 /// inconsistent locking.
59 /// \enum SK_LockedSomeLoopIterations -- a mutex is locked for some but not all
60 /// loop iterations.
61 /// \enum SK_LockedSomePredecessors -- a mutex is locked in some but not all
62 /// predecessors of a CFGBlock.
63 /// \enum SK_LockedAtEndOfFunction -- a mutex is still locked at the end of a
64 /// function.
65 enum LockErrorKind {
66   LEK_LockedSomeLoopIterations,
67   LEK_LockedSomePredecessors,
68   LEK_LockedAtEndOfFunction,
69   LEK_NotLockedAtEndOfFunction
70 };
71
72 /// Handler class for thread safety warnings.
73 class ThreadSafetyHandler {
74 public:
75   typedef StringRef Name;
76   ThreadSafetyHandler() : IssueBetaWarnings(false) { }
77   virtual ~ThreadSafetyHandler();
78
79   /// Warn about lock expressions which fail to resolve to lockable objects.
80   /// \param Kind -- the capability's name parameter (role, mutex, etc).
81   /// \param Loc -- the SourceLocation of the unresolved expression.
82   virtual void handleInvalidLockExp(StringRef Kind, SourceLocation Loc) {}
83
84   /// Warn about unlock function calls that do not have a prior matching lock
85   /// expression.
86   /// \param Kind -- the capability's name parameter (role, mutex, etc).
87   /// \param LockName -- A StringRef name for the lock expression, to be printed
88   /// in the error message.
89   /// \param Loc -- The SourceLocation of the Unlock
90   virtual void handleUnmatchedUnlock(StringRef Kind, Name LockName,
91                                      SourceLocation Loc) {}
92
93   /// Warn about an unlock function call that attempts to unlock a lock with
94   /// the incorrect lock kind. For instance, a shared lock being unlocked
95   /// exclusively, or vice versa.
96   /// \param LockName -- A StringRef name for the lock expression, to be printed
97   /// in the error message.
98   /// \param Kind -- the capability's name parameter (role, mutex, etc).
99   /// \param Expected -- the kind of lock expected.
100   /// \param Received -- the kind of lock received.
101   /// \param Loc -- The SourceLocation of the Unlock.
102   virtual void handleIncorrectUnlockKind(StringRef Kind, Name LockName,
103                                          LockKind Expected, LockKind Received,
104                                          SourceLocation Loc) {}
105
106   /// Warn about lock function calls for locks which are already held.
107   /// \param Kind -- the capability's name parameter (role, mutex, etc).
108   /// \param LockName -- A StringRef name for the lock expression, to be printed
109   /// in the error message.
110   /// \param Loc -- The location of the second lock expression.
111   virtual void handleDoubleLock(StringRef Kind, Name LockName,
112                                 SourceLocation Loc) {}
113
114   /// Warn about situations where a mutex is sometimes held and sometimes not.
115   /// The three situations are:
116   /// 1. a mutex is locked on an "if" branch but not the "else" branch,
117   /// 2, or a mutex is only held at the start of some loop iterations,
118   /// 3. or when a mutex is locked but not unlocked inside a function.
119   /// \param Kind -- the capability's name parameter (role, mutex, etc).
120   /// \param LockName -- A StringRef name for the lock expression, to be printed
121   /// in the error message.
122   /// \param LocLocked -- The location of the lock expression where the mutex is
123   ///               locked
124   /// \param LocEndOfScope -- The location of the end of the scope where the
125   ///               mutex is no longer held
126   /// \param LEK -- which of the three above cases we should warn for
127   virtual void handleMutexHeldEndOfScope(StringRef Kind, Name LockName,
128                                          SourceLocation LocLocked,
129                                          SourceLocation LocEndOfScope,
130                                          LockErrorKind LEK) {}
131
132   /// Warn when a mutex is held exclusively and shared at the same point. For
133   /// example, if a mutex is locked exclusively during an if branch and shared
134   /// during the else branch.
135   /// \param Kind -- the capability's name parameter (role, mutex, etc).
136   /// \param LockName -- A StringRef name for the lock expression, to be printed
137   /// in the error message.
138   /// \param Loc1 -- The location of the first lock expression.
139   /// \param Loc2 -- The location of the second lock expression.
140   virtual void handleExclusiveAndShared(StringRef Kind, Name LockName,
141                                         SourceLocation Loc1,
142                                         SourceLocation Loc2) {}
143
144   /// Warn when a protected operation occurs while no locks are held.
145   /// \param Kind -- the capability's name parameter (role, mutex, etc).
146   /// \param D -- The decl for the protected variable or function
147   /// \param POK -- The kind of protected operation (e.g. variable access)
148   /// \param AK -- The kind of access (i.e. read or write) that occurred
149   /// \param Loc -- The location of the protected operation.
150   virtual void handleNoMutexHeld(StringRef Kind, const NamedDecl *D,
151                                  ProtectedOperationKind POK, AccessKind AK,
152                                  SourceLocation Loc) {}
153
154   /// Warn when a protected operation occurs while the specific mutex protecting
155   /// the operation is not locked.
156   /// \param Kind -- the capability's name parameter (role, mutex, etc).
157   /// \param D -- The decl for the protected variable or function
158   /// \param POK -- The kind of protected operation (e.g. variable access)
159   /// \param LockName -- A StringRef name for the lock expression, to be printed
160   /// in the error message.
161   /// \param LK -- The kind of access (i.e. read or write) that occurred
162   /// \param Loc -- The location of the protected operation.
163   virtual void handleMutexNotHeld(StringRef Kind, const NamedDecl *D,
164                                   ProtectedOperationKind POK, Name LockName,
165                                   LockKind LK, SourceLocation Loc,
166                                   Name *PossibleMatch = nullptr) {}
167
168   /// Warn when acquiring a lock that the negative capability is not held.
169   /// \param Kind -- the capability's name parameter (role, mutex, etc).
170   /// \param LockName -- The name for the lock expression, to be printed in the
171   /// diagnostic.
172   /// \param Neg -- The name of the negative capability to be printed in the
173   /// diagnostic.
174   /// \param Loc -- The location of the protected operation.
175   virtual void handleNegativeNotHeld(StringRef Kind, Name LockName, Name Neg,
176                                      SourceLocation Loc) {}
177
178   /// Warn when a function is called while an excluded mutex is locked. For
179   /// example, the mutex may be locked inside the function.
180   /// \param Kind -- the capability's name parameter (role, mutex, etc).
181   /// \param FunName -- The name of the function
182   /// \param LockName -- A StringRef name for the lock expression, to be printed
183   /// in the error message.
184   /// \param Loc -- The location of the function call.
185   virtual void handleFunExcludesLock(StringRef Kind, Name FunName,
186                                      Name LockName, SourceLocation Loc) {}
187
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
196   /// Called by the analysis when starting analysis of a function.
197   /// Used to issue suggestions for changes to annotations.
198   virtual void enterFunction(const FunctionDecl *FD) {}
199
200   /// Called by the analysis when finishing analysis of a function.
201   virtual void leaveFunction(const FunctionDecl *FD) {}
202
203   bool issueBetaWarnings() { return IssueBetaWarnings; }
204   void setIssueBetaWarnings(bool b) { IssueBetaWarnings = b; }
205
206 private:
207   bool IssueBetaWarnings;
208 };
209
210 /// \brief Check a function's CFG for thread-safety violations.
211 ///
212 /// We traverse the blocks in the CFG, compute the set of mutexes that are held
213 /// at the end of each block, and issue warnings for thread safety violations.
214 /// Each block in the CFG is traversed exactly once.
215 void runThreadSafetyAnalysis(AnalysisDeclContext &AC,
216                              ThreadSafetyHandler &Handler,
217                              BeforeSet **Bset);
218
219 void threadSafetyCleanup(BeforeSet *Cache);
220
221 /// \brief Helper function that returns a LockKind required for the given level
222 /// of access.
223 LockKind getLockKindFromAccessKind(AccessKind AK);
224
225 }} // end namespace clang::threadSafety
226 #endif