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