/usr/include/clang/Analysis/Analyses/ThreadSafety.h is in libclang-dev 3.0-6ubuntu3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | //===- ThreadSafety.h ------------------------------------------*- C++ --*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//
// A intra-procedural analysis for thread safety (e.g. deadlocks and race
// conditions), based off of an annotation system.
//
// See http://clang.llvm.org/docs/LanguageExtensions.html#threadsafety for more
// information.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_THREADSAFETY_H
#define LLVM_CLANG_THREADSAFETY_H
#include "clang/Analysis/AnalysisContext.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/StringRef.h"
namespace clang {
namespace thread_safety {
/// This enum distinguishes between different kinds of operations that may
/// need to be protected by locks. We use this enum in error handling.
enum ProtectedOperationKind {
POK_VarDereference, /// Dereferencing a variable (e.g. p in *p = 5;)
POK_VarAccess, /// Reading or writing a variable (e.g. x in x = 5;)
POK_FunctionCall /// Making a function call (e.g. fool())
};
/// This enum distinguishes between different kinds of lock actions. For
/// example, it is an error to write a variable protected by shared version of a
/// mutex.
enum LockKind {
LK_Shared, /// Shared/reader lock of a mutex
LK_Exclusive /// Exclusive/writer lock of a mutex
};
/// This enum distinguishes between different ways to access (read or write) a
/// variable.
enum AccessKind {
AK_Read, /// Reading a variable
AK_Written /// Writing a variable
};
/// This enum distinguishes between different situations where we warn due to
/// inconsistent locking.
/// \enum SK_LockedSomeLoopIterations -- a mutex is locked for some but not all
/// loop iterations.
/// \enum SK_LockedSomePredecessors -- a mutex is locked in some but not all
/// predecessors of a CFGBlock.
/// \enum SK_LockedAtEndOfFunction -- a mutex is still locked at the end of a
/// function.
enum LockErrorKind {
LEK_LockedSomeLoopIterations,
LEK_LockedSomePredecessors,
LEK_LockedAtEndOfFunction
};
/// Handler class for thread safety warnings.
class ThreadSafetyHandler {
public:
typedef llvm::StringRef Name;
virtual ~ThreadSafetyHandler() = 0;
/// Warn about lock expressions which fail to resolve to lockable objects.
/// \param Loc -- the SourceLocation of the unresolved expression.
virtual void handleInvalidLockExp(SourceLocation Loc) {}
/// Warn about unlock function calls that do not have a prior matching lock
/// expression.
/// \param LockName -- A StringRef name for the lock expression, to be printed
/// in the error message.
/// \param Loc -- The SourceLocation of the Unlock
virtual void handleUnmatchedUnlock(Name LockName, SourceLocation Loc) {}
/// Warn about lock function calls for locks which are already held.
/// \param LockName -- A StringRef name for the lock expression, to be printed
/// in the error message.
/// \param Loc -- The location of the second lock expression.
virtual void handleDoubleLock(Name LockName, SourceLocation Loc) {}
/// Warn about situations where a mutex is sometimes held and sometimes not.
/// The three situations are:
/// 1. a mutex is locked on an "if" branch but not the "else" branch,
/// 2, or a mutex is only held at the start of some loop iterations,
/// 3. or when a mutex is locked but not unlocked inside a function.
/// \param LockName -- A StringRef name for the lock expression, to be printed
/// in the error message.
/// \param Loc -- The location of the lock expression where the mutex is locked
/// \param LEK -- which of the three above cases we should warn for
virtual void handleMutexHeldEndOfScope(Name LockName, SourceLocation Loc,
LockErrorKind LEK){}
/// Warn when a mutex is held exclusively and shared at the same point. For
/// example, if a mutex is locked exclusively during an if branch and shared
/// during the else branch.
/// \param LockName -- A StringRef name for the lock expression, to be printed
/// in the error message.
/// \param Loc1 -- The location of the first lock expression.
/// \param Loc2 -- The location of the second lock expression.
virtual void handleExclusiveAndShared(Name LockName, SourceLocation Loc1,
SourceLocation Loc2) {}
/// Warn when a protected operation occurs while no locks are held.
/// \param D -- The decl for the protected variable or function
/// \param POK -- The kind of protected operation (e.g. variable access)
/// \param AK -- The kind of access (i.e. read or write) that occurred
/// \param Loc -- The location of the protected operation.
virtual void handleNoMutexHeld(const NamedDecl *D, ProtectedOperationKind POK,
AccessKind AK, SourceLocation Loc) {}
/// Warn when a protected operation occurs while the specific mutex protecting
/// the operation is not locked.
/// \param LockName -- A StringRef name for the lock expression, to be printed
/// in the error message.
/// \param D -- The decl for the protected variable or function
/// \param POK -- The kind of protected operation (e.g. variable access)
/// \param AK -- The kind of access (i.e. read or write) that occurred
/// \param Loc -- The location of the protected operation.
virtual void handleMutexNotHeld(const NamedDecl *D,
ProtectedOperationKind POK, Name LockName,
LockKind LK, SourceLocation Loc) {}
/// Warn when a function is called while an excluded mutex is locked. For
/// example, the mutex may be locked inside the function.
/// \param FunName -- The name of the function
/// \param LockName -- A StringRef name for the lock expression, to be printed
/// in the error message.
/// \param Loc -- The location of the function call.
virtual void handleFunExcludesLock(Name FunName, Name LockName,
SourceLocation Loc) {}
};
/// \brief Check a function's CFG for thread-safety violations.
///
/// We traverse the blocks in the CFG, compute the set of mutexes that are held
/// at the end of each block, and issue warnings for thread safety violations.
/// Each block in the CFG is traversed exactly once.
void runThreadSafetyAnalysis(AnalysisContext &AC, ThreadSafetyHandler &Handler);
/// \brief Helper function that returns a LockKind required for the given level
/// of access.
LockKind getLockKindFromAccessKind(AccessKind AK);
}} // end namespace clang::thread_safety
#endif
|