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