ThreadSafety.h revision 19903465e960329c0d5d93327f4046d036b0bc75
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#threadsafety for more 15// 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 26namespace clang { 27namespace 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 POK_VarDereference -- Dereferencing a variable (e.g. p in *p = 5;) 32/// \enum POK_VarAccess -- Reading or writing a variable (e.g. x in x = 5;) 33/// \enum POK_FunctionCall -- making a function call (e.g. fool()) 34enum ProtectedOperationKind { 35 POK_VarDereference, 36 POK_VarAccess, 37 POK_FunctionCall 38}; 39 40/// This enum distinguishes between different kinds of lock actions. For 41/// example, it is an error to write a variable protected by shared version of a 42/// mutex. 43/// \enum LK_Shared -- Shared/reader lock of a mutex 44/// \enum LK_Exclusive -- Exclusive/writer lock of a mutex 45enum LockKind { 46 LK_Shared, 47 LK_Exclusive 48}; 49 50/// This enum distinguishes between different ways to access (read or write) a 51/// variable. 52/// \enum AK_Read -- reading a variable 53/// \enum AK_Written -- writing a variable 54enum AccessKind { 55 AK_Read, 56 AK_Written 57}; 58 59/// Handler class for thread safety warnings. 60class ThreadSafetyHandler { 61public: 62 typedef llvm::StringRef Name; 63 virtual ~ThreadSafetyHandler() = 0; 64 65 /// Warn about lock expressions which fail to resolve to lockable objects. 66 /// \param Loc -- the SourceLocation of the unresolved expression. 67 virtual void handleInvalidLockExp(SourceLocation Loc) {} 68 69 /// Warn about unlock function calls that do not have a prior matching lock 70 /// expression. 71 /// \param LockName -- A StringRef name for the lock expression, to be printed 72 /// in the error message. 73 /// \param Loc -- The SourceLocation of the Unlock 74 virtual void handleUnmatchedUnlock(Name LockName, SourceLocation Loc) {} 75 76 /// Warn about lock function calls for locks which are already held. 77 /// \param LockName -- A StringRef name for the lock expression, to be printed 78 /// in the error message. 79 /// \param Loc -- The Loc of the second lock expression. 80 virtual void handleDoubleLock(Name LockName, SourceLocation Loc) {} 81 82 /// Warn about situations where a mutex is sometimes held and sometimes not. 83 /// For example, a mutex is locked on an "if" branch but not the "else" 84 /// branch. 85 /// \param LockName -- A StringRef name for the lock expression, to be printed 86 /// in the error message. 87 /// \param Loc -- The Loc of the lock expression where the mutex is locked 88 virtual void handleMutexHeldEndOfScope(Name LockName, SourceLocation Loc){} 89 90 /// Warn when a mutex is only held at the start of some loop iterations. 91 /// \param LockName -- A StringRef name for the lock expression, to be printed 92 /// in the error message. 93 /// \param Loc -- The Loc of the lock expression. 94 virtual void handleNoLockLoopEntry(Name LockName, SourceLocation Loc) {} 95 96 /// Warn when a mutex is locked but not unlocked inside a function. 97 /// \param LockName -- A StringRef name for the lock expression, to be printed 98 /// in the error message. 99 /// \param FunName -- The name of the function 100 /// \param Loc -- The Loc of the lock expression 101 virtual void handleNoUnlock(Name LockName, Name FunName, 102 SourceLocation Loc) {} 103 104 /// Warn when a mutex is held exclusively and shared at the same point. For 105 /// example, if a mutex is locked exclusively during an if branch and shared 106 /// during the else branch. 107 /// \param LockName -- A StringRef name for the lock expression, to be printed 108 /// in the error message. 109 /// \param Loc1 -- The Loc of the first lock expression. 110 /// \param Loc2 -- The Loc of the second lock expression. 111 virtual void handleExclusiveAndShared(Name LockName, SourceLocation Loc1, 112 SourceLocation Loc2) {} 113 114 /// Warn when a protected operation occurs while no locks are held. 115 /// \param D -- The decl for the protected variable or function 116 /// \param POK -- The kind of protected operation (e.g. variable access) 117 /// \param AK -- The kind of access (i.e. read or write) that occurred 118 /// \param Loc -- The Loc of the protected operation. 119 virtual void handleNoMutexHeld(const NamedDecl *D, ProtectedOperationKind POK, 120 AccessKind AK, SourceLocation Loc) {} 121 122 /// Warn when a protected operation occurs while the specific mutex protecting 123 /// the operation is not locked. 124 /// \param LockName -- A StringRef name for the lock expression, to be printed 125 /// in the error message. 126 /// \param D -- The decl for the protected variable or function 127 /// \param POK -- The kind of protected operation (e.g. variable access) 128 /// \param AK -- The kind of access (i.e. read or write) that occurred 129 /// \param Loc -- The Loc of the protected operation. 130 virtual void handleMutexNotHeld(const NamedDecl *D, 131 ProtectedOperationKind POK, Name LockName, 132 LockKind LK, SourceLocation Loc) {} 133 134 /// Warn when a function is called while an excluded mutex is locked. For 135 /// example, the mutex may be locked inside the function. 136 /// \param FunName -- The name of the function 137 /// \param LockName -- A StringRef name for the lock expression, to be printed 138 /// in the error message. 139 /// \param Loc -- The Loc of the function call. 140 virtual void handleFunExcludesLock(Name FunName, Name LockName, 141 SourceLocation Loc) {} 142}; 143 144/// \brief Check a function's CFG for thread-safety violations. 145/// 146/// We traverse the blocks in the CFG, compute the set of mutexes that are held 147/// at the end of each block, and issue warnings for thread safety violations. 148/// Each block in the CFG is traversed exactly once. 149void runThreadSafetyAnalysis(AnalysisContext &AC, ThreadSafetyHandler &Handler); 150 151/// \brief Helper function that returns a LockKind required for the given level 152/// of access. 153LockKind getLockKindFromAccessKind(AccessKind AK); 154 155}} // end namespace clang::thread_safety 156#endif 157