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, 634e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski LEK_LockedAtEndOfFunction 644e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski}; 654e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski 6619903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// Handler class for thread safety warnings. 67402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowskiclass ThreadSafetyHandler { 68402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowskipublic: 69402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski typedef llvm::StringRef Name; 709f80a97408ee0da939654d851ff42ad07d47e9c7DeLesley Hutchins virtual ~ThreadSafetyHandler(); 7119903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski 7219903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// Warn about lock expressions which fail to resolve to lockable objects. 7319903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param Loc -- the SourceLocation of the unresolved expression. 7499107ebc0a5aea953b736e12757e0919d5249d43Caitlin Sadowski virtual void handleInvalidLockExp(SourceLocation Loc) {} 7519903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski 7619903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// Warn about unlock function calls that do not have a prior matching lock 7719903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// expression. 7819903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param LockName -- A StringRef name for the lock expression, to be printed 7919903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// in the error message. 8019903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param Loc -- The SourceLocation of the Unlock 81402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski virtual void handleUnmatchedUnlock(Name LockName, SourceLocation Loc) {} 8219903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski 8319903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// Warn about lock function calls for locks which are already held. 8419903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param LockName -- A StringRef name for the lock expression, to be printed 8519903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// in the error message. 86b50dd472cd6c8b13213626f13a928dbe41581f09Caitlin Sadowski /// \param Loc -- The location of the second lock expression. 87402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski virtual void handleDoubleLock(Name LockName, SourceLocation Loc) {} 8819903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski 8919903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// Warn about situations where a mutex is sometimes held and sometimes not. 904e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski /// The three situations are: 914e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski /// 1. a mutex is locked on an "if" branch but not the "else" branch, 924e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski /// 2, or a mutex is only held at the start of some loop iterations, 934e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski /// 3. or when a mutex is locked but not unlocked inside a function. 9419903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param LockName -- A StringRef name for the lock expression, to be printed 9519903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// in the error message. 962e5156274b8051217565b557bfa14c80f7990e9cRichard Smith /// \param LocLocked -- The location of the lock expression where the mutex is 97ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie /// locked 982e5156274b8051217565b557bfa14c80f7990e9cRichard Smith /// \param LocEndOfScope -- The location of the end of the scope where the 992e5156274b8051217565b557bfa14c80f7990e9cRichard Smith /// mutex is no longer held 1004e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski /// \param LEK -- which of the three above cases we should warn for 1012e5156274b8051217565b557bfa14c80f7990e9cRichard Smith virtual void handleMutexHeldEndOfScope(Name LockName, 1022e5156274b8051217565b557bfa14c80f7990e9cRichard Smith SourceLocation LocLocked, 1032e5156274b8051217565b557bfa14c80f7990e9cRichard Smith SourceLocation LocEndOfScope, 1044e4bc75d3570835e13183c66ac08974cdc016007Caitlin Sadowski LockErrorKind LEK){} 10519903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski 10619903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// Warn when a mutex is held exclusively and shared at the same point. For 10719903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// example, if a mutex is locked exclusively during an if branch and shared 10819903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// during the else branch. 10919903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param LockName -- A StringRef name for the lock expression, to be printed 11019903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// in the error message. 111b50dd472cd6c8b13213626f13a928dbe41581f09Caitlin Sadowski /// \param Loc1 -- The location of the first lock expression. 112b50dd472cd6c8b13213626f13a928dbe41581f09Caitlin Sadowski /// \param Loc2 -- The location of the second lock expression. 113402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski virtual void handleExclusiveAndShared(Name LockName, SourceLocation Loc1, 114402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski SourceLocation Loc2) {} 11519903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski 11619903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// Warn when a protected operation occurs while no locks are held. 11719903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param D -- The decl for the protected variable or function 11819903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param POK -- The kind of protected operation (e.g. variable access) 11919903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param AK -- The kind of access (i.e. read or write) that occurred 120b50dd472cd6c8b13213626f13a928dbe41581f09Caitlin Sadowski /// \param Loc -- The location of the protected operation. 121402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski virtual void handleNoMutexHeld(const NamedDecl *D, ProtectedOperationKind POK, 122402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski AccessKind AK, SourceLocation Loc) {} 12319903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski 12419903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// Warn when a protected operation occurs while the specific mutex protecting 12519903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// the operation is not locked. 12619903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param LockName -- A StringRef name for the lock expression, to be printed 12719903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// in the error message. 12819903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param D -- The decl for the protected variable or function 12919903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param POK -- The kind of protected operation (e.g. variable access) 13019903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param AK -- The kind of access (i.e. read or write) that occurred 131b50dd472cd6c8b13213626f13a928dbe41581f09Caitlin Sadowski /// \param Loc -- The location of the protected operation. 132402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski virtual void handleMutexNotHeld(const NamedDecl *D, 133402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski ProtectedOperationKind POK, Name LockName, 134402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski LockKind LK, SourceLocation Loc) {} 13519903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski 13619903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// Warn when a function is called while an excluded mutex is locked. For 13719903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// example, the mutex may be locked inside the function. 13819903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param FunName -- The name of the function 13919903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// \param LockName -- A StringRef name for the lock expression, to be printed 14019903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski /// in the error message. 141b50dd472cd6c8b13213626f13a928dbe41581f09Caitlin Sadowski /// \param Loc -- The location of the function call. 142402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski virtual void handleFunExcludesLock(Name FunName, Name LockName, 143402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski SourceLocation Loc) {} 144402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski}; 145402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski 14619903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// \brief Check a function's CFG for thread-safety violations. 14719903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// 14819903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// We traverse the blocks in the CFG, compute the set of mutexes that are held 14919903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// at the end of each block, and issue warnings for thread safety violations. 15019903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// Each block in the CFG is traversed exactly once. 151ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikievoid runThreadSafetyAnalysis(AnalysisDeclContext &AC, 152ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie ThreadSafetyHandler &Handler); 15319903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski 15419903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// \brief Helper function that returns a LockKind required for the given level 15519903465e960329c0d5d93327f4046d036b0bc75Caitlin Sadowski/// of access. 156402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin SadowskiLockKind getLockKindFromAccessKind(AccessKind AK); 157402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski 158402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski}} // end namespace clang::thread_safety 159402aa0698fec81e574818a0a6c2000fac0b2c4c6Caitlin Sadowski#endif 160