<div class="gmail_quote">On Wed, Sep 14, 2011 at 1:05 PM, Caitlin Sadowski <span dir="ltr"><<a href="mailto:supertri@google.com">supertri@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Author: supertri<br>
Date: Wed Sep 14 15:05:09 2011<br>
New Revision: 139722<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=139722&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=139722&view=rev</a><br>
Log:<br>
Thread safety: adding additional documentation to the main thread safety interface, and making the destructor for the thread safety handler pure virtual<br>
<br>
Modified:<br>
cfe/trunk/include/clang/Analysis/Analyses/ThreadSafety.h<br>
cfe/trunk/lib/Analysis/ThreadSafety.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Analysis/Analyses/ThreadSafety.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/ThreadSafety.h?rev=139722&r1=139721&r2=139722&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/ThreadSafety.h?rev=139722&r1=139721&r2=139722&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Analysis/Analyses/ThreadSafety.h (original)<br>
+++ cfe/trunk/include/clang/Analysis/Analyses/ThreadSafety.h Wed Sep 14 15:05:09 2011<br>
@@ -11,7 +11,8 @@<br>
// A intra-procedural analysis for thread safety (e.g. deadlocks and race<br>
// conditions), based off of an annotation system.<br>
//<br>
-// See <a href="http://gcc.gnu.org/wiki/ThreadSafetyAnnotation" target="_blank">http://gcc.gnu.org/wiki/ThreadSafetyAnnotation</a> for the gcc version.<br>
+// See <a href="http://clang.llvm.org/docs/LanguageExtensions.html#threadsafety" target="_blank">http://clang.llvm.org/docs/LanguageExtensions.html#threadsafety</a> for more<br>
+// information.<br>
//<br>
//===----------------------------------------------------------------------===//<br>
<br>
@@ -25,46 +26,130 @@<br>
namespace clang {<br>
namespace thread_safety {<br>
<br>
+/// This enum distinguishes between different kinds of operations that may<br>
+/// need to be protected by locks. We use this enum in error handling.<br>
+/// \enum POK_VarDereference -- Dereferencing a variable (e.g. p in *p = 5;)<br></blockquote><div><br></div><div>Rather than using \enum here, I suspect you can just put the content after the '--' in a doxygen comment before the enumerator, or even on the same line.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
+/// \enum POK_VarAccess -- Reading or writing a variable (e.g. x in x = 5;)<br>
+/// \enum POK_FunctionCall -- making a function call (e.g. fool())<br>
enum ProtectedOperationKind { </blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
POK_VarDereference,<br>
POK_VarAccess,<br>
POK_FunctionCall<br>
};<br>
<br>
+/// This enum distinguishes between different kinds of lock actions. For<br>
+/// example, it is an error to write a variable protected by shared version of a<br>
+/// mutex.<br>
+/// \enum LK_Shared -- Shared/reader lock of a mutex<br>
+/// \enum LK_Exclusive -- Exclusive/writer lock of a mutex<br>
enum LockKind {<br>
LK_Shared,<br>
LK_Exclusive<br>
};<br>
<br>
+/// This enum distinguishes between different ways to access (read or write) a<br>
+/// variable.<br>
+/// \enum AK_Read -- reading a variable<br>
+/// \enum AK_Written -- writing a variable<br>
enum AccessKind {<br>
AK_Read,<br>
AK_Written<br>
};<br>
<br>
+/// Handler class for thread safety warnings.<br>
class ThreadSafetyHandler {<br>
public:<br>
typedef llvm::StringRef Name;<br>
- ThreadSafetyHandler() {}<br>
- virtual ~ThreadSafetyHandler() {}<br>
+ virtual ~ThreadSafetyHandler() = 0;<br></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">+<br>
+ /// Warn about lock expressions which fail to resolve to lockable objects.<br>
+ /// \param Loc -- the SourceLocation of the unresolved expression.<br>
virtual void handleInvalidLockExp(SourceLocation Loc) {}<br>
+<br>
+ /// Warn about unlock function calls that do not have a prior matching lock<br>
+ /// expression.<br>
+ /// \param LockName -- A StringRef name for the lock expression, to be printed<br>
+ /// in the error message.<br>
+ /// \param Loc -- The SourceLocation of the Unlock<br>
virtual void handleUnmatchedUnlock(Name LockName, SourceLocation Loc) {}<br>
+<br>
+ /// Warn about lock function calls for locks which are already held.<br>
+ /// \param LockName -- A StringRef name for the lock expression, to be printed<br>
+ /// in the error message.<br>
+ /// \param Loc -- The Loc of the second lock expression.<br></blockquote><div><br></div><div>Here and below I would expand the abbreviation in your prose when you're not referring to the specific named object. Essentially:</div>
<div>s/The Loc/The location/</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
virtual void handleDoubleLock(Name LockName, SourceLocation Loc) {}<br>
+<br>
+ /// Warn about situations where a mutex is sometimes held and sometimes not.<br>
+ /// For example, a mutex is locked on an "if" branch but not the "else"<br>
+ /// branch.<br>
+ /// \param LockName -- A StringRef name for the lock expression, to be printed<br>
+ /// in the error message.<br>
+ /// \param Loc -- The Loc of the lock expression where the mutex is locked<br>
virtual void handleMutexHeldEndOfScope(Name LockName, SourceLocation Loc){}<br>
+<br>
+ /// Warn when a mutex is only held at the start of some loop iterations.<br>
+ /// \param LockName -- A StringRef name for the lock expression, to be printed<br>
+ /// in the error message.<br>
+ /// \param Loc -- The Loc of the lock expression.<br>
virtual void handleNoLockLoopEntry(Name LockName, SourceLocation Loc) {}<br>
+<br>
+ /// Warn when a mutex is locked but not unlocked inside a function.<br>
+ /// \param LockName -- A StringRef name for the lock expression, to be printed<br>
+ /// in the error message.<br>
+ /// \param FunName -- The name of the function<br>
+ /// \param Loc -- The Loc of the lock expression<br>
virtual void handleNoUnlock(Name LockName, Name FunName,<br>
SourceLocation Loc) {}<br>
+<br>
+ /// Warn when a mutex is held exclusively and shared at the same point. For<br>
+ /// example, if a mutex is locked exclusively during an if branch and shared<br>
+ /// during the else branch.<br>
+ /// \param LockName -- A StringRef name for the lock expression, to be printed<br>
+ /// in the error message.<br>
+ /// \param Loc1 -- The Loc of the first lock expression.<br>
+ /// \param Loc2 -- The Loc of the second lock expression.<br>
virtual void handleExclusiveAndShared(Name LockName, SourceLocation Loc1,<br>
SourceLocation Loc2) {}<br>
+<br>
+ /// Warn when a protected operation occurs while no locks are held.<br>
+ /// \param D -- The decl for the protected variable or function<br>
+ /// \param POK -- The kind of protected operation (e.g. variable access)<br>
+ /// \param AK -- The kind of access (i.e. read or write) that occurred<br>
+ /// \param Loc -- The Loc of the protected operation.<br>
virtual void handleNoMutexHeld(const NamedDecl *D, ProtectedOperationKind POK,<br>
AccessKind AK, SourceLocation Loc) {}<br>
+<br>
+ /// Warn when a protected operation occurs while the specific mutex protecting<br>
+ /// the operation is not locked.<br>
+ /// \param LockName -- A StringRef name for the lock expression, to be printed<br>
+ /// in the error message.<br>
+ /// \param D -- The decl for the protected variable or function<br>
+ /// \param POK -- The kind of protected operation (e.g. variable access)<br>
+ /// \param AK -- The kind of access (i.e. read or write) that occurred<br>
+ /// \param Loc -- The Loc of the protected operation.<br>
virtual void handleMutexNotHeld(const NamedDecl *D,<br>
ProtectedOperationKind POK, Name LockName,<br>
LockKind LK, SourceLocation Loc) {}<br>
+<br>
+ /// Warn when a function is called while an excluded mutex is locked. For<br>
+ /// example, the mutex may be locked inside the function.<br>
+ /// \param FunName -- The name of the function<br>
+ /// \param LockName -- A StringRef name for the lock expression, to be printed<br>
+ /// in the error message.<br>
+ /// \param Loc -- The Loc of the function call.<br>
virtual void handleFunExcludesLock(Name FunName, Name LockName,<br>
SourceLocation Loc) {}<br>
};<br>
<br>
+/// \brief Check a function's CFG for thread-safety violations.<br>
+///<br>
+/// We traverse the blocks in the CFG, compute the set of mutexes that are held<br>
+/// at the end of each block, and issue warnings for thread safety violations.<br>
+/// Each block in the CFG is traversed exactly once.<br>
void runThreadSafetyAnalysis(AnalysisContext &AC, ThreadSafetyHandler &Handler);<br>
+<br>
+/// \brief Helper function that returns a LockKind required for the given level<br>
+/// of access.<br>
LockKind getLockKindFromAccessKind(AccessKind AK);<br>
<br>
}} // end namespace clang::thread_safety<br>
<br>
Modified: cfe/trunk/lib/Analysis/ThreadSafety.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ThreadSafety.cpp?rev=139722&r1=139721&r2=139722&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ThreadSafety.cpp?rev=139722&r1=139721&r2=139722&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Analysis/ThreadSafety.cpp (original)<br>
+++ cfe/trunk/lib/Analysis/ThreadSafety.cpp Wed Sep 14 15:05:09 2011<br>
@@ -10,7 +10,8 @@<br>
// A intra-procedural analysis for thread safety (e.g. deadlocks and race<br>
// conditions), based off of an annotation system.<br>
//<br>
-// See <a href="http://gcc.gnu.org/wiki/ThreadSafetyAnnotation" target="_blank">http://gcc.gnu.org/wiki/ThreadSafetyAnnotation</a> for the gcc version.<br>
+// See <a href="http://clang.llvm.org/docs/LanguageExtensions.html#threadsafety" target="_blank">http://clang.llvm.org/docs/LanguageExtensions.html#threadsafety</a> for more<br>
+// information.<br>
//<br>
//===----------------------------------------------------------------------===//<br>
<br>
@@ -36,6 +37,9 @@<br>
using namespace clang;<br>
using namespace thread_safety;<br>
<br>
+// Key method definition<br>
+ThreadSafetyHandler::~ThreadSafetyHandler() {}<br>
+<br>
// Helper functions<br>
static Expr *getParent(Expr *Exp) {<br>
if (MemberExpr *ME = dyn_cast<MemberExpr>(Exp))<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br>