clang API Documentation

ThreadSafety.h
Go to the documentation of this file.
00001 //===- ThreadSafety.h ------------------------------------------*- C++ --*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //
00011 // A intra-procedural analysis for thread safety (e.g. deadlocks and race
00012 // conditions), based off of an annotation system.
00013 //
00014 // See http://clang.llvm.org/docs/LanguageExtensions.html#thread-safety-annotation-checking
00015 // for more information.
00016 //
00017 //===----------------------------------------------------------------------===//
00018 
00019 #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
00020 #define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
00021 
00022 #include "clang/Analysis/AnalysisContext.h"
00023 #include "clang/Basic/SourceLocation.h"
00024 #include "llvm/ADT/StringRef.h"
00025 
00026 namespace clang {
00027 namespace threadSafety {
00028 
00029 /// This enum distinguishes between different kinds of operations that may
00030 /// need to be protected by locks. We use this enum in error handling.
00031 enum ProtectedOperationKind {
00032   POK_VarDereference, ///< Dereferencing a variable (e.g. p in *p = 5;)
00033   POK_VarAccess, ///< Reading or writing a variable (e.g. x in x = 5;)
00034   POK_FunctionCall, ///< Making a function call (e.g. fool())
00035   POK_PassByRef, ///< Passing a guarded variable by reference.
00036   POK_PtPassByRef,  ///< Passing a pt-guarded variable by reference.
00037 };
00038 
00039 /// This enum distinguishes between different kinds of lock actions. For
00040 /// example, it is an error to write a variable protected by shared version of a
00041 /// mutex.
00042 enum LockKind {
00043   LK_Shared,    ///< Shared/reader lock of a mutex.
00044   LK_Exclusive, ///< Exclusive/writer lock of a mutex.
00045   LK_Generic    ///< Can be either Shared or Exclusive
00046 };
00047 
00048 /// This enum distinguishes between different ways to access (read or write) a
00049 /// variable.
00050 enum AccessKind {
00051   AK_Read, ///< Reading a variable.
00052   AK_Written ///< Writing a variable.
00053 };
00054 
00055 /// This enum distinguishes between different situations where we warn due to
00056 /// inconsistent locking.
00057 /// \enum SK_LockedSomeLoopIterations -- a mutex is locked for some but not all
00058 /// loop iterations.
00059 /// \enum SK_LockedSomePredecessors -- a mutex is locked in some but not all
00060 /// predecessors of a CFGBlock.
00061 /// \enum SK_LockedAtEndOfFunction -- a mutex is still locked at the end of a
00062 /// function.
00063 enum LockErrorKind {
00064   LEK_LockedSomeLoopIterations,
00065   LEK_LockedSomePredecessors,
00066   LEK_LockedAtEndOfFunction,
00067   LEK_NotLockedAtEndOfFunction
00068 };
00069 
00070 /// Handler class for thread safety warnings.
00071 class ThreadSafetyHandler {
00072 public:
00073   typedef StringRef Name;
00074   ThreadSafetyHandler() : IssueBetaWarnings(false) { }
00075   virtual ~ThreadSafetyHandler();
00076 
00077   /// Warn about lock expressions which fail to resolve to lockable objects.
00078   /// \param Kind -- the capability's name parameter (role, mutex, etc).
00079   /// \param Loc -- the SourceLocation of the unresolved expression.
00080   virtual void handleInvalidLockExp(StringRef Kind, SourceLocation Loc) {}
00081 
00082   /// Warn about unlock function calls that do not have a prior matching lock
00083   /// expression.
00084   /// \param Kind -- the capability's name parameter (role, mutex, etc).
00085   /// \param LockName -- A StringRef name for the lock expression, to be printed
00086   /// in the error message.
00087   /// \param Loc -- The SourceLocation of the Unlock
00088   virtual void handleUnmatchedUnlock(StringRef Kind, Name LockName,
00089                                      SourceLocation Loc) {}
00090 
00091   /// Warn about an unlock function call that attempts to unlock a lock with
00092   /// the incorrect lock kind. For instance, a shared lock being unlocked
00093   /// exclusively, or vice versa.
00094   /// \param LockName -- A StringRef name for the lock expression, to be printed
00095   /// in the error message.
00096   /// \param Kind -- the capability's name parameter (role, mutex, etc).
00097   /// \param Expected -- the kind of lock expected.
00098   /// \param Received -- the kind of lock received.
00099   /// \param Loc -- The SourceLocation of the Unlock.
00100   virtual void handleIncorrectUnlockKind(StringRef Kind, Name LockName,
00101                                          LockKind Expected, LockKind Received,
00102                                          SourceLocation Loc) {}
00103 
00104   /// Warn about lock function calls for locks which are already held.
00105   /// \param Kind -- the capability's name parameter (role, mutex, etc).
00106   /// \param LockName -- A StringRef name for the lock expression, to be printed
00107   /// in the error message.
00108   /// \param Loc -- The location of the second lock expression.
00109   virtual void handleDoubleLock(StringRef Kind, Name LockName,
00110                                 SourceLocation Loc) {}
00111 
00112   /// Warn about situations where a mutex is sometimes held and sometimes not.
00113   /// The three situations are:
00114   /// 1. a mutex is locked on an "if" branch but not the "else" branch,
00115   /// 2, or a mutex is only held at the start of some loop iterations,
00116   /// 3. or when a mutex is locked but not unlocked inside a function.
00117   /// \param Kind -- the capability's name parameter (role, mutex, etc).
00118   /// \param LockName -- A StringRef name for the lock expression, to be printed
00119   /// in the error message.
00120   /// \param LocLocked -- The location of the lock expression where the mutex is
00121   ///               locked
00122   /// \param LocEndOfScope -- The location of the end of the scope where the
00123   ///               mutex is no longer held
00124   /// \param LEK -- which of the three above cases we should warn for
00125   virtual void handleMutexHeldEndOfScope(StringRef Kind, Name LockName,
00126                                          SourceLocation LocLocked,
00127                                          SourceLocation LocEndOfScope,
00128                                          LockErrorKind LEK) {}
00129 
00130   /// Warn when a mutex is held exclusively and shared at the same point. For
00131   /// example, if a mutex is locked exclusively during an if branch and shared
00132   /// during the else branch.
00133   /// \param Kind -- the capability's name parameter (role, mutex, etc).
00134   /// \param LockName -- A StringRef name for the lock expression, to be printed
00135   /// in the error message.
00136   /// \param Loc1 -- The location of the first lock expression.
00137   /// \param Loc2 -- The location of the second lock expression.
00138   virtual void handleExclusiveAndShared(StringRef Kind, Name LockName,
00139                                         SourceLocation Loc1,
00140                                         SourceLocation Loc2) {}
00141 
00142   /// Warn when a protected operation occurs while no locks are held.
00143   /// \param Kind -- the capability's name parameter (role, mutex, etc).
00144   /// \param D -- The decl for the protected variable or function
00145   /// \param POK -- The kind of protected operation (e.g. variable access)
00146   /// \param AK -- The kind of access (i.e. read or write) that occurred
00147   /// \param Loc -- The location of the protected operation.
00148   virtual void handleNoMutexHeld(StringRef Kind, const NamedDecl *D,
00149                                  ProtectedOperationKind POK, AccessKind AK,
00150                                  SourceLocation Loc) {}
00151 
00152   /// Warn when a protected operation occurs while the specific mutex protecting
00153   /// the operation is not locked.
00154   /// \param Kind -- the capability's name parameter (role, mutex, etc).
00155   /// \param D -- The decl for the protected variable or function
00156   /// \param POK -- The kind of protected operation (e.g. variable access)
00157   /// \param LockName -- A StringRef name for the lock expression, to be printed
00158   /// in the error message.
00159   /// \param LK -- The kind of access (i.e. read or write) that occurred
00160   /// \param Loc -- The location of the protected operation.
00161   virtual void handleMutexNotHeld(StringRef Kind, const NamedDecl *D,
00162                                   ProtectedOperationKind POK, Name LockName,
00163                                   LockKind LK, SourceLocation Loc,
00164                                   Name *PossibleMatch = nullptr) {}
00165 
00166   /// Warn when acquiring a lock that the negative capability is not held.
00167   /// \param Kind -- the capability's name parameter (role, mutex, etc).
00168   /// \param LockName -- The name for the lock expression, to be printed in the
00169   /// diagnostic.
00170   /// \param Neg -- The name of the negative capability to be printed in the
00171   /// diagnostic.
00172   /// \param Loc -- The location of the protected operation.
00173   virtual void handleNegativeNotHeld(StringRef Kind, Name LockName, Name Neg,
00174                                      SourceLocation Loc) {}
00175 
00176   /// Warn when a function is called while an excluded mutex is locked. For
00177   /// example, the mutex may be locked inside the function.
00178   /// \param Kind -- the capability's name parameter (role, mutex, etc).
00179   /// \param FunName -- The name of the function
00180   /// \param LockName -- A StringRef name for the lock expression, to be printed
00181   /// in the error message.
00182   /// \param Loc -- The location of the function call.
00183   virtual void handleFunExcludesLock(StringRef Kind, Name FunName,
00184                                      Name LockName, SourceLocation Loc) {}
00185 
00186   /// Called by the analysis when starting analysis of a function.
00187   /// Used to issue suggestions for changes to annotations.
00188   virtual void enterFunction(const FunctionDecl *FD) {}
00189 
00190   /// Called by the analysis when finishing analysis of a function.
00191   virtual void leaveFunction(const FunctionDecl *FD) {}
00192 
00193   bool issueBetaWarnings() { return IssueBetaWarnings; }
00194   void setIssueBetaWarnings(bool b) { IssueBetaWarnings = b; }
00195 
00196 private:
00197   bool IssueBetaWarnings;
00198 };
00199 
00200 /// \brief Check a function's CFG for thread-safety violations.
00201 ///
00202 /// We traverse the blocks in the CFG, compute the set of mutexes that are held
00203 /// at the end of each block, and issue warnings for thread safety violations.
00204 /// Each block in the CFG is traversed exactly once.
00205 void runThreadSafetyAnalysis(AnalysisDeclContext &AC,
00206                              ThreadSafetyHandler &Handler);
00207 
00208 /// \brief Helper function that returns a LockKind required for the given level
00209 /// of access.
00210 LockKind getLockKindFromAccessKind(AccessKind AK);
00211 
00212 }} // end namespace clang::threadSafety
00213 #endif