]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ThreadSafety.h
Merge ^/head r274961 through r276418.
[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_THREADSAFETY_H
20 #define LLVM_CLANG_THREADSAFETY_H
21
22 #include "clang/Analysis/AnalysisContext.h"
23 #include "clang/Basic/SourceLocation.h"
24 #include "llvm/ADT/StringRef.h"
25
26 namespace clang {
27 namespace thread_safety {
28
29 /// This enum distinguishes between different kinds of operations that may
30 /// need to be protected by locks. We use this enum in error handling.
31 enum ProtectedOperationKind {
32   POK_VarDereference, ///< Dereferencing a variable (e.g. p in *p = 5;)
33   POK_VarAccess, ///< Reading or writing a variable (e.g. x in x = 5;)
34   POK_FunctionCall ///< Making a function call (e.g. fool())
35 };
36
37 /// This enum distinguishes between different kinds of lock actions. For
38 /// example, it is an error to write a variable protected by shared version of a
39 /// mutex.
40 enum LockKind {
41   LK_Shared, ///< Shared/reader lock of a mutex.
42   LK_Exclusive, ///< Exclusive/writer lock of a mutex.
43   LK_Generic  ///<  Can be either Shared or Exclusive
44 };
45
46 /// This enum distinguishes between different ways to access (read or write) a
47 /// variable.
48 enum AccessKind {
49   AK_Read, ///< Reading a variable.
50   AK_Written ///< Writing a variable.
51 };
52
53 /// This enum distinguishes between different situations where we warn due to
54 /// inconsistent locking.
55 /// \enum SK_LockedSomeLoopIterations -- a mutex is locked for some but not all
56 /// loop iterations.
57 /// \enum SK_LockedSomePredecessors -- a mutex is locked in some but not all
58 /// predecessors of a CFGBlock.
59 /// \enum SK_LockedAtEndOfFunction -- a mutex is still locked at the end of a
60 /// function.
61 enum LockErrorKind {
62   LEK_LockedSomeLoopIterations,
63   LEK_LockedSomePredecessors,
64   LEK_LockedAtEndOfFunction,
65   LEK_NotLockedAtEndOfFunction
66 };
67
68 /// Handler class for thread safety warnings.
69 class ThreadSafetyHandler {
70 public:
71   typedef StringRef Name;
72   ThreadSafetyHandler() : IssueBetaWarnings(false) { }
73   virtual ~ThreadSafetyHandler();
74
75   /// Warn about lock expressions which fail to resolve to lockable objects.
76   /// \param Kind -- the capability's name parameter (role, mutex, etc).
77   /// \param Loc -- the SourceLocation of the unresolved expression.
78   virtual void handleInvalidLockExp(StringRef Kind, SourceLocation Loc) {}
79
80   /// Warn about unlock function calls that do not have a prior matching lock
81   /// expression.
82   /// \param Kind -- the capability's name parameter (role, mutex, etc).
83   /// \param LockName -- A StringRef name for the lock expression, to be printed
84   /// in the error message.
85   /// \param Loc -- The SourceLocation of the Unlock
86   virtual void handleUnmatchedUnlock(StringRef Kind, Name LockName,
87                                      SourceLocation Loc) {}
88
89   /// Warn about an unlock function call that attempts to unlock a lock with
90   /// the incorrect lock kind. For instance, a shared lock being unlocked
91   /// exclusively, or vice versa.
92   /// \param LockName -- A StringRef name for the lock expression, to be printed
93   /// in the error message.
94   /// \param Kind -- the capability's name parameter (role, mutex, etc).
95   /// \param Expected -- the kind of lock expected.
96   /// \param Received -- the kind of lock received.
97   /// \param Loc -- The SourceLocation of the Unlock.
98   virtual void handleIncorrectUnlockKind(StringRef Kind, Name LockName,
99                                          LockKind Expected, LockKind Received,
100                                          SourceLocation Loc) {}
101
102   /// Warn about lock function calls for locks which are already held.
103   /// \param Kind -- the capability's name parameter (role, mutex, etc).
104   /// \param LockName -- A StringRef name for the lock expression, to be printed
105   /// in the error message.
106   /// \param Loc -- The location of the second lock expression.
107   virtual void handleDoubleLock(StringRef Kind, Name LockName,
108                                 SourceLocation Loc) {}
109
110   /// Warn about situations where a mutex is sometimes held and sometimes not.
111   /// The three situations are:
112   /// 1. a mutex is locked on an "if" branch but not the "else" branch,
113   /// 2, or a mutex is only held at the start of some loop iterations,
114   /// 3. or when a mutex is locked but not unlocked inside a function.
115   /// \param Kind -- the capability's name parameter (role, mutex, etc).
116   /// \param LockName -- A StringRef name for the lock expression, to be printed
117   /// in the error message.
118   /// \param LocLocked -- The location of the lock expression where the mutex is
119   ///               locked
120   /// \param LocEndOfScope -- The location of the end of the scope where the
121   ///               mutex is no longer held
122   /// \param LEK -- which of the three above cases we should warn for
123   virtual void handleMutexHeldEndOfScope(StringRef Kind, Name LockName,
124                                          SourceLocation LocLocked,
125                                          SourceLocation LocEndOfScope,
126                                          LockErrorKind LEK) {}
127
128   /// Warn when a mutex is held exclusively and shared at the same point. For
129   /// example, if a mutex is locked exclusively during an if branch and shared
130   /// during the else branch.
131   /// \param Kind -- the capability's name parameter (role, mutex, etc).
132   /// \param LockName -- A StringRef name for the lock expression, to be printed
133   /// in the error message.
134   /// \param Loc1 -- The location of the first lock expression.
135   /// \param Loc2 -- The location of the second lock expression.
136   virtual void handleExclusiveAndShared(StringRef Kind, Name LockName,
137                                         SourceLocation Loc1,
138                                         SourceLocation Loc2) {}
139
140   /// Warn when a protected operation occurs while no locks are held.
141   /// \param Kind -- the capability's name parameter (role, mutex, etc).
142   /// \param D -- The decl for the protected variable or function
143   /// \param POK -- The kind of protected operation (e.g. variable access)
144   /// \param AK -- The kind of access (i.e. read or write) that occurred
145   /// \param Loc -- The location of the protected operation.
146   virtual void handleNoMutexHeld(StringRef Kind, const NamedDecl *D,
147                                  ProtectedOperationKind POK, AccessKind AK,
148                                  SourceLocation Loc) {}
149
150   /// Warn when a protected operation occurs while the specific mutex protecting
151   /// the operation is not locked.
152   /// \param Kind -- the capability's name parameter (role, mutex, etc).
153   /// \param D -- The decl for the protected variable or function
154   /// \param POK -- The kind of protected operation (e.g. variable access)
155   /// \param LockName -- A StringRef name for the lock expression, to be printed
156   /// in the error message.
157   /// \param LK -- The kind of access (i.e. read or write) that occurred
158   /// \param Loc -- The location of the protected operation.
159   virtual void handleMutexNotHeld(StringRef Kind, const NamedDecl *D,
160                                   ProtectedOperationKind POK, Name LockName,
161                                   LockKind LK, SourceLocation Loc,
162                                   Name *PossibleMatch = nullptr) {}
163
164   /// Warn when a function is called while an excluded mutex is locked. For
165   /// example, the mutex may be locked inside the function.
166   /// \param Kind -- the capability's name parameter (role, mutex, etc).
167   /// \param FunName -- The name of the function
168   /// \param LockName -- A StringRef name for the lock expression, to be printed
169   /// in the error message.
170   /// \param Loc -- The location of the function call.
171   virtual void handleFunExcludesLock(StringRef Kind, Name FunName,
172                                      Name LockName, SourceLocation Loc) {}
173
174   bool issueBetaWarnings() { return IssueBetaWarnings; }
175   void setIssueBetaWarnings(bool b) { IssueBetaWarnings = b; }
176
177 private:
178   bool IssueBetaWarnings;
179 };
180
181 /// \brief Check a function's CFG for thread-safety violations.
182 ///
183 /// We traverse the blocks in the CFG, compute the set of mutexes that are held
184 /// at the end of each block, and issue warnings for thread safety violations.
185 /// Each block in the CFG is traversed exactly once.
186 void runThreadSafetyAnalysis(AnalysisDeclContext &AC,
187                              ThreadSafetyHandler &Handler);
188
189 /// \brief Helper function that returns a LockKind required for the given level
190 /// of access.
191 LockKind getLockKindFromAccessKind(AccessKind AK);
192
193 }} // end namespace clang::thread_safety
194 #endif