ThreadSafety.h revision 879a4334e4c4cab0c22ba91492ffc2838bbc21fc
1402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski//===- ThreadSafety.h ------------------------------------------*- C++ --*-===// 2402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski// 3402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski// The LLVM Compiler Infrastructure 4402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski// 5402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski// This file is distributed under the University of Illinois Open Source 6402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski// License. See LICENSE.TXT for details. 7402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski// 8402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski//===----------------------------------------------------------------------===// 9402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski// 10402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski// 11402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski// A intra-procedural analysis for thread safety (e.g. deadlocks and race 12402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski// conditions), based off of an annotation system. 13402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski// 1419903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski// See http://clang.llvm.org/docs/LanguageExtensions.html#threadsafety for more 1519903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski// information. 16402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski// 17402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski//===----------------------------------------------------------------------===// 18402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski 19402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski#ifndef LLVM_CLANG_THREADSAFETY_H 20402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski#define LLVM_CLANG_THREADSAFETY_H 21402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski 22d5b16055782034ca90153880c36bd88b59c63aa0Caitlin Sadowski#include "clang/Analysis/AnalysisContext.h" 23402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski#include "clang/Basic/SourceLocation.h" 24402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski#include "llvm/ADT/StringRef.h" 25402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski 26402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowskinamespace clang { 27402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowskinamespace thread_safety { 28402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski 2919903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// This enum distinguishes between different kinds of operations that may 3019903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// need to be protected by locks. We use this enum in error handling. 31402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowskienum ProtectedOperationKind { 32b50dd472cd6c8b13213626f13a928dbe41581f09Caitlin Sadowski POK_VarDereference, /// Dereferencing a variable (e.g. p in *p = 5;) 33b50dd472cd6c8b13213626f13a928dbe41581f09Caitlin Sadowski POK_VarAccess, /// Reading or writing a variable (e.g. x in x = 5;) 34b50dd472cd6c8b13213626f13a928dbe41581f09Caitlin Sadowski POK_FunctionCall /// Making a function call (e.g. fool()) 35402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski}; 36402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski 3719903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// This enum distinguishes between different kinds of lock actions. For 3819903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// example, it is an error to write a variable protected by shared version of a 3919903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// mutex. 40402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowskienum LockKind { 41b50dd472cd6c8b13213626f13a928dbe41581f09Caitlin Sadowski LK_Shared, /// Shared/reader lock of a mutex 42b50dd472cd6c8b13213626f13a928dbe41581f09Caitlin Sadowski LK_Exclusive /// Exclusive/writer lock of a mutex 43402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski}; 44402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski 4519903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// This enum distinguishes between different ways to access (read or write) a 4619903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// variable. 47402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowskienum AccessKind { 48b50dd472cd6c8b13213626f13a928dbe41581f09Caitlin Sadowski AK_Read, /// Reading a variable 49b50dd472cd6c8b13213626f13a928dbe41581f09Caitlin Sadowski AK_Written /// Writing a variable 50402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski}; 51402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski 524e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski/// This enum distinguishes between different situations where we warn due to 534e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski/// inconsistent locking. 544e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski/// \enum SK_LockedSomeLoopIterations -- a mutex is locked for some but not all 554e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski/// loop iterations. 564e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski/// \enum SK_LockedSomePredecessors -- a mutex is locked in some but not all 574e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski/// predecessors of a CFGBlock. 584e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski/// \enum SK_LockedAtEndOfFunction -- a mutex is still locked at the end of a 594e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski/// function. 604e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowskienum LockErrorKind { 614e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski LEK_LockedSomeLoopIterations, 624e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski LEK_LockedSomePredecessors, 63879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins LEK_LockedAtEndOfFunction, 64879a4334e4c4cab0c22ba91492ffc2838bbc21fcDeLesley Hutchins LEK_NotLockedAtEndOfFunction 654e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski}; 664e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski 6719903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// Handler class for thread safety warnings. 68402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowskiclass ThreadSafetyHandler { 69402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowskipublic: 70402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski typedef llvm::StringRef Name; 719f80a97408ee0da939654d851ff42ad07d47e9c7DeLesley Hutchins virtual ~ThreadSafetyHandler(); 7219903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski 7319903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// Warn about lock expressions which fail to resolve to lockable objects. 7419903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param Loc -- the SourceLocation of the unresolved expression. 7599107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski virtual void handleInvalidLockExp(SourceLocation Loc) {} 7619903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski 7719903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// Warn about unlock function calls that do not have a prior matching lock 7819903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// expression. 7919903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param LockName -- A StringRef name for the lock expression, to be printed 8019903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// in the error message. 8119903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param Loc -- The SourceLocation of the Unlock 82402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski virtual void handleUnmatchedUnlock(Name LockName, SourceLocation Loc) {} 8319903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski 8419903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// Warn about lock function calls for locks which are already held. 8519903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param LockName -- A StringRef name for the lock expression, to be printed 8619903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// in the error message. 87b50dd472cd6c8b13213626f13a928dbe41581f09Caitlin Sadowski /// \param Loc -- The location of the second lock expression. 88402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski virtual void handleDoubleLock(Name LockName, SourceLocation Loc) {} 8919903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski 9019903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// Warn about situations where a mutex is sometimes held and sometimes not. 914e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski /// The three situations are: 924e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski /// 1. a mutex is locked on an "if" branch but not the "else" branch, 934e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski /// 2, or a mutex is only held at the start of some loop iterations, 944e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski /// 3. or when a mutex is locked but not unlocked inside a function. 9519903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param LockName -- A StringRef name for the lock expression, to be printed 9619903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// in the error message. 972e5156274b8051217565b557bfa14c80f7990e9cRichard Smith /// \param LocLocked -- The location of the lock expression where the mutex is 98ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie /// locked 992e5156274b8051217565b557bfa14c80f7990e9cRichard Smith /// \param LocEndOfScope -- The location of the end of the scope where the 1002e5156274b8051217565b557bfa14c80f7990e9cRichard Smith /// mutex is no longer held 1014e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski /// \param LEK -- which of the three above cases we should warn for 1022e5156274b8051217565b557bfa14c80f7990e9cRichard Smith virtual void handleMutexHeldEndOfScope(Name LockName, 1032e5156274b8051217565b557bfa14c80f7990e9cRichard Smith SourceLocation LocLocked, 1042e5156274b8051217565b557bfa14c80f7990e9cRichard Smith SourceLocation LocEndOfScope, 1054e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski LockErrorKind LEK){} 10619903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski 10719903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// Warn when a mutex is held exclusively and shared at the same point. For 10819903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// example, if a mutex is locked exclusively during an if branch and shared 10919903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// during the else branch. 11019903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param LockName -- A StringRef name for the lock expression, to be printed 11119903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// in the error message. 112b50dd472cd6c8b13213626f13a928dbe41581f09Caitlin Sadowski /// \param Loc1 -- The location of the first lock expression. 113b50dd472cd6c8b13213626f13a928dbe41581f09Caitlin Sadowski /// \param Loc2 -- The location of the second lock expression. 114402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski virtual void handleExclusiveAndShared(Name LockName, SourceLocation Loc1, 115402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski SourceLocation Loc2) {} 11619903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski 11719903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// Warn when a protected operation occurs while no locks are held. 11819903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param D -- The decl for the protected variable or function 11919903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param POK -- The kind of protected operation (e.g. variable access) 12019903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param AK -- The kind of access (i.e. read or write) that occurred 121b50dd472cd6c8b13213626f13a928dbe41581f09Caitlin Sadowski /// \param Loc -- The location of the protected operation. 122402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski virtual void handleNoMutexHeld(const NamedDecl *D, ProtectedOperationKind POK, 123402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski AccessKind AK, SourceLocation Loc) {} 12419903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski 12519903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// Warn when a protected operation occurs while the specific mutex protecting 12619903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// the operation is not locked. 12719903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param D -- The decl for the protected variable or function 12819903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param POK -- The kind of protected operation (e.g. variable access) 129edd6d40770c9010883307b195acea6e9d732263aJames Dennett /// \param LockName -- A StringRef name for the lock expression, to be printed 130edd6d40770c9010883307b195acea6e9d732263aJames Dennett /// in the error message. 131edd6d40770c9010883307b195acea6e9d732263aJames Dennett /// \param LK -- The kind of access (i.e. read or write) that occurred 132b50dd472cd6c8b13213626f13a928dbe41581f09Caitlin Sadowski /// \param Loc -- The location of the protected operation. 133402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski virtual void handleMutexNotHeld(const NamedDecl *D, 134402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski ProtectedOperationKind POK, Name LockName, 135402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski LockKind LK, SourceLocation Loc) {} 13619903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski 13719903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// Warn when a function is called while an excluded mutex is locked. For 13819903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// example, the mutex may be locked inside the function. 13919903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param FunName -- The name of the function 14019903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param LockName -- A StringRef name for the lock expression, to be printed 14119903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// in the error message. 142b50dd472cd6c8b13213626f13a928dbe41581f09Caitlin Sadowski /// \param Loc -- The location of the function call. 143402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski virtual void handleFunExcludesLock(Name FunName, Name LockName, 144402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski SourceLocation Loc) {} 145402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski}; 146402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski 14719903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// \brief Check a function's CFG for thread-safety violations. 14819903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// 14919903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// We traverse the blocks in the CFG, compute the set of mutexes that are held 15019903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// at the end of each block, and issue warnings for thread safety violations. 15119903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// Each block in the CFG is traversed exactly once. 152ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikievoid runThreadSafetyAnalysis(AnalysisDeclContext &AC, 153ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie ThreadSafetyHandler &Handler); 15419903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski 15519903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// \brief Helper function that returns a LockKind required for the given level 15619903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// of access. 157402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin SadowskiLockKind getLockKindFromAccessKind(AccessKind AK); 158402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski 159402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski}} // end namespace clang::thread_safety 160402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski#endif 161