blob: 6f76f1b94738f20ee7052675377d7aba68c6f89e [file] [log] [blame]
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001//===- ThreadSafety.cpp ----------------------------------------*- 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// A intra-procedural analysis for thread safety (e.g. deadlocks and race
11// conditions), based off of an annotation system.
12//
Caitlin Sadowski19903462011-09-14 20:05:09 +000013// See http://clang.llvm.org/docs/LanguageExtensions.html#threadsafety for more
14// information.
Caitlin Sadowski402aa062011-09-09 16:11:56 +000015//
16//===----------------------------------------------------------------------===//
17
18#include "clang/Analysis/Analyses/ThreadSafety.h"
Ted Kremenek439ed162011-10-22 02:14:27 +000019#include "clang/Analysis/Analyses/PostOrderCFGView.h"
Caitlin Sadowskid5b16052011-09-09 23:00:59 +000020#include "clang/Analysis/AnalysisContext.h"
21#include "clang/Analysis/CFG.h"
22#include "clang/Analysis/CFGStmtMap.h"
Caitlin Sadowski402aa062011-09-09 16:11:56 +000023#include "clang/AST/DeclCXX.h"
24#include "clang/AST/ExprCXX.h"
25#include "clang/AST/StmtCXX.h"
26#include "clang/AST/StmtVisitor.h"
Caitlin Sadowskid5b16052011-09-09 23:00:59 +000027#include "clang/Basic/SourceManager.h"
28#include "clang/Basic/SourceLocation.h"
Caitlin Sadowski402aa062011-09-09 16:11:56 +000029#include "llvm/ADT/BitVector.h"
30#include "llvm/ADT/FoldingSet.h"
31#include "llvm/ADT/ImmutableMap.h"
32#include "llvm/ADT/PostOrderIterator.h"
33#include "llvm/ADT/SmallVector.h"
34#include "llvm/ADT/StringRef.h"
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +000035#include "llvm/Support/raw_ostream.h"
Caitlin Sadowski402aa062011-09-09 16:11:56 +000036#include <algorithm>
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +000037#include <utility>
Caitlin Sadowski402aa062011-09-09 16:11:56 +000038#include <vector>
39
40using namespace clang;
41using namespace thread_safety;
42
Caitlin Sadowski19903462011-09-14 20:05:09 +000043// Key method definition
44ThreadSafetyHandler::~ThreadSafetyHandler() {}
45
Caitlin Sadowski402aa062011-09-09 16:11:56 +000046namespace {
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +000047
Caitlin Sadowski402aa062011-09-09 16:11:56 +000048/// \brief A MutexID object uniquely identifies a particular mutex, and
49/// is built from an Expr* (i.e. calling a lock function).
50///
51/// Thread-safety analysis works by comparing lock expressions. Within the
52/// body of a function, an expression such as "x->foo->bar.mu" will resolve to
53/// a particular mutex object at run-time. Subsequent occurrences of the same
54/// expression (where "same" means syntactic equality) will refer to the same
55/// run-time object if three conditions hold:
56/// (1) Local variables in the expression, such as "x" have not changed.
57/// (2) Values on the heap that affect the expression have not changed.
58/// (3) The expression involves only pure function calls.
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +000059///
Caitlin Sadowski402aa062011-09-09 16:11:56 +000060/// The current implementation assumes, but does not verify, that multiple uses
61/// of the same lock expression satisfies these criteria.
62///
63/// Clang introduces an additional wrinkle, which is that it is difficult to
64/// derive canonical expressions, or compare expressions directly for equality.
65/// Thus, we identify a mutex not by an Expr, but by the set of named
66/// declarations that are referenced by the Expr. In other words,
67/// x->foo->bar.mu will be a four element vector with the Decls for
68/// mu, bar, and foo, and x. The vector will uniquely identify the expression
69/// for all practical purposes.
70///
71/// Note we will need to perform substitution on "this" and function parameter
72/// names when constructing a lock expression.
73///
74/// For example:
75/// class C { Mutex Mu; void lock() EXCLUSIVE_LOCK_FUNCTION(this->Mu); };
76/// void myFunc(C *X) { ... X->lock() ... }
77/// The original expression for the mutex acquired by myFunc is "this->Mu", but
78/// "X" is substituted for "this" so we get X->Mu();
79///
80/// For another example:
81/// foo(MyList *L) EXCLUSIVE_LOCKS_REQUIRED(L->Mu) { ... }
82/// MyList *MyL;
83/// foo(MyL); // requires lock MyL->Mu to be held
84class MutexID {
85 SmallVector<NamedDecl*, 2> DeclSeq;
86
87 /// Build a Decl sequence representing the lock from the given expression.
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +000088 /// Recursive function that terminates on DeclRefExpr.
89 /// Note: this function merely creates a MutexID; it does not check to
90 /// ensure that the original expression is a valid mutex expression.
DeLesley Hutchinse03b2b32012-01-20 23:24:41 +000091 void buildMutexID(Expr *Exp, const NamedDecl *D, Expr *Parent,
92 unsigned NumArgs, Expr **FunArgs) {
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +000093 if (!Exp) {
94 DeclSeq.clear();
95 return;
96 }
97
Caitlin Sadowski402aa062011-09-09 16:11:56 +000098 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Exp)) {
99 NamedDecl *ND = cast<NamedDecl>(DRE->getDecl()->getCanonicalDecl());
DeLesley Hutchinse03b2b32012-01-20 23:24:41 +0000100 ParmVarDecl *PV = dyn_cast_or_null<ParmVarDecl>(ND);
101 if (PV) {
102 FunctionDecl *FD =
103 cast<FunctionDecl>(PV->getDeclContext())->getCanonicalDecl();
104 unsigned i = PV->getFunctionScopeIndex();
105
106 if (FunArgs && FD == D->getCanonicalDecl()) {
107 // Substitute call arguments for references to function parameters
108 assert(i < NumArgs);
109 buildMutexID(FunArgs[i], D, 0, 0, 0);
110 return;
111 }
112 // Map the param back to the param of the original function declaration.
113 DeclSeq.push_back(FD->getParamDecl(i));
114 return;
115 }
116 // Not a function parameter -- just store the reference.
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000117 DeclSeq.push_back(ND);
118 } else if (MemberExpr *ME = dyn_cast<MemberExpr>(Exp)) {
119 NamedDecl *ND = ME->getMemberDecl();
120 DeclSeq.push_back(ND);
DeLesley Hutchinse03b2b32012-01-20 23:24:41 +0000121 buildMutexID(ME->getBase(), D, Parent, NumArgs, FunArgs);
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000122 } else if (isa<CXXThisExpr>(Exp)) {
Caitlin Sadowski194418f2011-09-14 20:00:24 +0000123 if (Parent)
DeLesley Hutchinse03b2b32012-01-20 23:24:41 +0000124 buildMutexID(Parent, D, 0, 0, 0);
Caitlin Sadowski194418f2011-09-14 20:00:24 +0000125 else
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000126 return; // mutexID is still valid in this case
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +0000127 } else if (UnaryOperator *UOE = dyn_cast<UnaryOperator>(Exp))
DeLesley Hutchinse03b2b32012-01-20 23:24:41 +0000128 buildMutexID(UOE->getSubExpr(), D, Parent, NumArgs, FunArgs);
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +0000129 else if (CastExpr *CE = dyn_cast<CastExpr>(Exp))
DeLesley Hutchinse03b2b32012-01-20 23:24:41 +0000130 buildMutexID(CE->getSubExpr(), D, Parent, NumArgs, FunArgs);
Caitlin Sadowski99107eb2011-09-09 16:21:55 +0000131 else
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000132 DeclSeq.clear(); // Mark as invalid lock expression.
133 }
134
135 /// \brief Construct a MutexID from an expression.
136 /// \param MutexExp The original mutex expression within an attribute
137 /// \param DeclExp An expression involving the Decl on which the attribute
138 /// occurs.
139 /// \param D The declaration to which the lock/unlock attribute is attached.
140 void buildMutexIDFromExp(Expr *MutexExp, Expr *DeclExp, const NamedDecl *D) {
141 Expr *Parent = 0;
DeLesley Hutchins81216392011-10-17 21:38:02 +0000142 unsigned NumArgs = 0;
143 Expr **FunArgs = 0;
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000144
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000145 // If we are processing a raw attribute expression, with no substitutions.
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000146 if (DeclExp == 0) {
DeLesley Hutchinse03b2b32012-01-20 23:24:41 +0000147 buildMutexID(MutexExp, D, 0, 0, 0);
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000148 return;
149 }
150
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +0000151 // Examine DeclExp to find Parent and FunArgs, which are used to substitute
152 // for formal parameters when we call buildMutexID later.
DeLesley Hutchins81216392011-10-17 21:38:02 +0000153 if (MemberExpr *ME = dyn_cast<MemberExpr>(DeclExp)) {
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000154 Parent = ME->getBase();
DeLesley Hutchins81216392011-10-17 21:38:02 +0000155 } else if (CXXMemberCallExpr *CE = dyn_cast<CXXMemberCallExpr>(DeclExp)) {
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000156 Parent = CE->getImplicitObjectArgument();
DeLesley Hutchins81216392011-10-17 21:38:02 +0000157 NumArgs = CE->getNumArgs();
158 FunArgs = CE->getArgs();
DeLesley Hutchinsdf497822011-12-29 00:56:48 +0000159 } else if (CallExpr *CE = dyn_cast<CallExpr>(DeclExp)) {
160 NumArgs = CE->getNumArgs();
161 FunArgs = CE->getArgs();
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +0000162 } else if (CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(DeclExp)) {
163 Parent = 0; // FIXME -- get the parent from DeclStmt
164 NumArgs = CE->getNumArgs();
165 FunArgs = CE->getArgs();
DeLesley Hutchins6db51f72011-10-21 20:51:27 +0000166 } else if (D && isa<CXXDestructorDecl>(D)) {
167 // There's no such thing as a "destructor call" in the AST.
168 Parent = DeclExp;
DeLesley Hutchins81216392011-10-17 21:38:02 +0000169 }
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000170
171 // If the attribute has no arguments, then assume the argument is "this".
172 if (MutexExp == 0) {
DeLesley Hutchinse03b2b32012-01-20 23:24:41 +0000173 buildMutexID(Parent, D, 0, 0, 0);
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000174 return;
175 }
DeLesley Hutchins81216392011-10-17 21:38:02 +0000176
DeLesley Hutchinse03b2b32012-01-20 23:24:41 +0000177 buildMutexID(MutexExp, D, Parent, NumArgs, FunArgs);
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000178 }
179
180public:
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000181 explicit MutexID(clang::Decl::EmptyShell e) {
182 DeclSeq.clear();
183 }
184
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000185 /// \param MutexExp The original mutex expression within an attribute
186 /// \param DeclExp An expression involving the Decl on which the attribute
187 /// occurs.
188 /// \param D The declaration to which the lock/unlock attribute is attached.
189 /// Caller must check isValid() after construction.
190 MutexID(Expr* MutexExp, Expr *DeclExp, const NamedDecl* D) {
191 buildMutexIDFromExp(MutexExp, DeclExp, D);
Caitlin Sadowski194418f2011-09-14 20:00:24 +0000192 }
193
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000194 /// Return true if this is a valid decl sequence.
195 /// Caller must call this by hand after construction to handle errors.
Caitlin Sadowski194418f2011-09-14 20:00:24 +0000196 bool isValid() const {
197 return !DeclSeq.empty();
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000198 }
199
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000200 /// Issue a warning about an invalid lock expression
201 static void warnInvalidLock(ThreadSafetyHandler &Handler, Expr* MutexExp,
202 Expr *DeclExp, const NamedDecl* D) {
203 SourceLocation Loc;
204 if (DeclExp)
205 Loc = DeclExp->getExprLoc();
206
207 // FIXME: add a note about the attribute location in MutexExp or D
208 if (Loc.isValid())
209 Handler.handleInvalidLockExp(Loc);
210 }
211
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000212 bool operator==(const MutexID &other) const {
213 return DeclSeq == other.DeclSeq;
214 }
215
216 bool operator!=(const MutexID &other) const {
217 return !(*this == other);
218 }
219
220 // SmallVector overloads Operator< to do lexicographic ordering. Note that
221 // we use pointer equality (and <) to compare NamedDecls. This means the order
222 // of MutexIDs in a lockset is nondeterministic. In order to output
223 // diagnostics in a deterministic ordering, we must order all diagnostics to
224 // output by SourceLocation when iterating through this lockset.
225 bool operator<(const MutexID &other) const {
226 return DeclSeq < other.DeclSeq;
227 }
228
229 /// \brief Returns the name of the first Decl in the list for a given MutexID;
230 /// e.g. the lock expression foo.bar() has name "bar".
231 /// The caret will point unambiguously to the lock expression, so using this
232 /// name in diagnostics is a way to get simple, and consistent, mutex names.
233 /// We do not want to output the entire expression text for security reasons.
234 StringRef getName() const {
Caitlin Sadowski194418f2011-09-14 20:00:24 +0000235 assert(isValid());
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000236 return DeclSeq.front()->getName();
237 }
238
239 void Profile(llvm::FoldingSetNodeID &ID) const {
240 for (SmallVectorImpl<NamedDecl*>::const_iterator I = DeclSeq.begin(),
241 E = DeclSeq.end(); I != E; ++I) {
242 ID.AddPointer(*I);
243 }
244 }
245};
246
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000247
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000248/// \brief This is a helper class that stores info about the most recent
249/// accquire of a Lock.
250///
251/// The main body of the analysis maps MutexIDs to LockDatas.
252struct LockData {
253 SourceLocation AcquireLoc;
254
255 /// \brief LKind stores whether a lock is held shared or exclusively.
256 /// Note that this analysis does not currently support either re-entrant
257 /// locking or lock "upgrading" and "downgrading" between exclusive and
258 /// shared.
259 ///
260 /// FIXME: add support for re-entrant locking and lock up/downgrading
261 LockKind LKind;
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000262 MutexID UnderlyingMutex; // for ScopedLockable objects
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000263
264 LockData(SourceLocation AcquireLoc, LockKind LKind)
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000265 : AcquireLoc(AcquireLoc), LKind(LKind), UnderlyingMutex(Decl::EmptyShell())
266 {}
267
268 LockData(SourceLocation AcquireLoc, LockKind LKind, const MutexID &Mu)
269 : AcquireLoc(AcquireLoc), LKind(LKind), UnderlyingMutex(Mu) {}
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000270
271 bool operator==(const LockData &other) const {
272 return AcquireLoc == other.AcquireLoc && LKind == other.LKind;
273 }
274
275 bool operator!=(const LockData &other) const {
276 return !(*this == other);
277 }
278
279 void Profile(llvm::FoldingSetNodeID &ID) const {
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000280 ID.AddInteger(AcquireLoc.getRawEncoding());
281 ID.AddInteger(LKind);
282 }
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000283};
284
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000285
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000286/// A Lockset maps each MutexID (defined above) to information about how it has
287/// been locked.
288typedef llvm::ImmutableMap<MutexID, LockData> Lockset;
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +0000289typedef llvm::ImmutableMap<NamedDecl*, unsigned> LocalVarContext;
290
291class LocalVariableMap;
292
293
294/// CFGBlockInfo is a struct which contains all the information that is
295/// maintained for each block in the CFG. See LocalVariableMap for more
296/// information about the contexts.
297struct CFGBlockInfo {
298 Lockset EntrySet; // Lockset held at entry to block
299 Lockset ExitSet; // Lockset held at exit from block
300 LocalVarContext EntryContext; // Context held at entry to block
301 LocalVarContext ExitContext; // Context held at exit from block
302 unsigned EntryIndex; // Used to replay contexts later
303
304private:
305 CFGBlockInfo(Lockset EmptySet, LocalVarContext EmptyCtx)
306 : EntrySet(EmptySet), ExitSet(EmptySet),
307 EntryContext(EmptyCtx), ExitContext(EmptyCtx)
308 { }
309
310public:
311 static CFGBlockInfo getEmptyBlockInfo(Lockset::Factory &F,
312 LocalVariableMap &M);
313};
314
315
316
317// A LocalVariableMap maintains a map from local variables to their currently
318// valid definitions. It provides SSA-like functionality when traversing the
319// CFG. Like SSA, each definition or assignment to a variable is assigned a
320// unique name (an integer), which acts as the SSA name for that definition.
321// The total set of names is shared among all CFG basic blocks.
322// Unlike SSA, we do not rewrite expressions to replace local variables declrefs
323// with their SSA-names. Instead, we compute a Context for each point in the
324// code, which maps local variables to the appropriate SSA-name. This map
325// changes with each assignment.
326//
327// The map is computed in a single pass over the CFG. Subsequent analyses can
328// then query the map to find the appropriate Context for a statement, and use
329// that Context to look up the definitions of variables.
330class LocalVariableMap {
331public:
332 typedef LocalVarContext Context;
333
334 /// A VarDefinition consists of an expression, representing the value of the
335 /// variable, along with the context in which that expression should be
336 /// interpreted. A reference VarDefinition does not itself contain this
337 /// information, but instead contains a pointer to a previous VarDefinition.
338 struct VarDefinition {
339 public:
340 friend class LocalVariableMap;
341
342 NamedDecl *Dec; // The original declaration for this variable.
343 Expr *Exp; // The expression for this variable, OR
344 unsigned Ref; // Reference to another VarDefinition
345 Context Ctx; // The map with which Exp should be interpreted.
346
347 bool isReference() { return !Exp; }
348
349 private:
350 // Create ordinary variable definition
351 VarDefinition(NamedDecl *D, Expr *E, Context C)
352 : Dec(D), Exp(E), Ref(0), Ctx(C)
353 { }
354
355 // Create reference to previous definition
356 VarDefinition(NamedDecl *D, unsigned R, Context C)
357 : Dec(D), Exp(0), Ref(R), Ctx(C)
358 { }
359 };
360
361private:
362 Context::Factory ContextFactory;
363 std::vector<VarDefinition> VarDefinitions;
364 std::vector<unsigned> CtxIndices;
365 std::vector<std::pair<Stmt*, Context> > SavedContexts;
366
367public:
368 LocalVariableMap() {
369 // index 0 is a placeholder for undefined variables (aka phi-nodes).
370 VarDefinitions.push_back(VarDefinition(0, 0u, getEmptyContext()));
371 }
372
373 /// Look up a definition, within the given context.
374 const VarDefinition* lookup(NamedDecl *D, Context Ctx) {
375 const unsigned *i = Ctx.lookup(D);
376 if (!i)
377 return 0;
378 assert(*i < VarDefinitions.size());
379 return &VarDefinitions[*i];
380 }
381
382 /// Look up the definition for D within the given context. Returns
DeLesley Hutchinsb4fa4182012-01-06 19:16:50 +0000383 /// NULL if the expression is not statically known. If successful, also
384 /// modifies Ctx to hold the context of the return Expr.
385 Expr* lookupExpr(NamedDecl *D, Context &Ctx) {
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +0000386 const unsigned *P = Ctx.lookup(D);
387 if (!P)
388 return 0;
389
390 unsigned i = *P;
391 while (i > 0) {
DeLesley Hutchinsb4fa4182012-01-06 19:16:50 +0000392 if (VarDefinitions[i].Exp) {
393 Ctx = VarDefinitions[i].Ctx;
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +0000394 return VarDefinitions[i].Exp;
DeLesley Hutchinsb4fa4182012-01-06 19:16:50 +0000395 }
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +0000396 i = VarDefinitions[i].Ref;
397 }
398 return 0;
399 }
400
401 Context getEmptyContext() { return ContextFactory.getEmptyMap(); }
402
403 /// Return the next context after processing S. This function is used by
404 /// clients of the class to get the appropriate context when traversing the
405 /// CFG. It must be called for every assignment or DeclStmt.
406 Context getNextContext(unsigned &CtxIndex, Stmt *S, Context C) {
407 if (SavedContexts[CtxIndex+1].first == S) {
408 CtxIndex++;
409 Context Result = SavedContexts[CtxIndex].second;
410 return Result;
411 }
412 return C;
413 }
414
415 void dumpVarDefinitionName(unsigned i) {
416 if (i == 0) {
417 llvm::errs() << "Undefined";
418 return;
419 }
420 NamedDecl *Dec = VarDefinitions[i].Dec;
421 if (!Dec) {
422 llvm::errs() << "<<NULL>>";
423 return;
424 }
425 Dec->printName(llvm::errs());
426 llvm::errs() << "." << i << " " << ((void*) Dec);
427 }
428
429 /// Dumps an ASCII representation of the variable map to llvm::errs()
430 void dump() {
431 for (unsigned i = 1, e = VarDefinitions.size(); i < e; ++i) {
432 Expr *Exp = VarDefinitions[i].Exp;
433 unsigned Ref = VarDefinitions[i].Ref;
434
435 dumpVarDefinitionName(i);
436 llvm::errs() << " = ";
437 if (Exp) Exp->dump();
438 else {
439 dumpVarDefinitionName(Ref);
440 llvm::errs() << "\n";
441 }
442 }
443 }
444
445 /// Dumps an ASCII representation of a Context to llvm::errs()
446 void dumpContext(Context C) {
447 for (Context::iterator I = C.begin(), E = C.end(); I != E; ++I) {
448 NamedDecl *D = I.getKey();
449 D->printName(llvm::errs());
450 const unsigned *i = C.lookup(D);
451 llvm::errs() << " -> ";
452 dumpVarDefinitionName(*i);
453 llvm::errs() << "\n";
454 }
455 }
456
457 /// Builds the variable map.
458 void traverseCFG(CFG *CFGraph, PostOrderCFGView *SortedGraph,
459 std::vector<CFGBlockInfo> &BlockInfo);
460
461protected:
462 // Get the current context index
463 unsigned getContextIndex() { return SavedContexts.size()-1; }
464
465 // Save the current context for later replay
466 void saveContext(Stmt *S, Context C) {
467 SavedContexts.push_back(std::make_pair(S,C));
468 }
469
470 // Adds a new definition to the given context, and returns a new context.
471 // This method should be called when declaring a new variable.
472 Context addDefinition(NamedDecl *D, Expr *Exp, Context Ctx) {
473 assert(!Ctx.contains(D));
474 unsigned newID = VarDefinitions.size();
475 Context NewCtx = ContextFactory.add(Ctx, D, newID);
476 VarDefinitions.push_back(VarDefinition(D, Exp, Ctx));
477 return NewCtx;
478 }
479
480 // Add a new reference to an existing definition.
481 Context addReference(NamedDecl *D, unsigned i, Context Ctx) {
482 unsigned newID = VarDefinitions.size();
483 Context NewCtx = ContextFactory.add(Ctx, D, newID);
484 VarDefinitions.push_back(VarDefinition(D, i, Ctx));
485 return NewCtx;
486 }
487
488 // Updates a definition only if that definition is already in the map.
489 // This method should be called when assigning to an existing variable.
490 Context updateDefinition(NamedDecl *D, Expr *Exp, Context Ctx) {
491 if (Ctx.contains(D)) {
492 unsigned newID = VarDefinitions.size();
493 Context NewCtx = ContextFactory.remove(Ctx, D);
494 NewCtx = ContextFactory.add(NewCtx, D, newID);
495 VarDefinitions.push_back(VarDefinition(D, Exp, Ctx));
496 return NewCtx;
497 }
498 return Ctx;
499 }
500
501 // Removes a definition from the context, but keeps the variable name
502 // as a valid variable. The index 0 is a placeholder for cleared definitions.
503 Context clearDefinition(NamedDecl *D, Context Ctx) {
504 Context NewCtx = Ctx;
505 if (NewCtx.contains(D)) {
506 NewCtx = ContextFactory.remove(NewCtx, D);
507 NewCtx = ContextFactory.add(NewCtx, D, 0);
508 }
509 return NewCtx;
510 }
511
512 // Remove a definition entirely frmo the context.
513 Context removeDefinition(NamedDecl *D, Context Ctx) {
514 Context NewCtx = Ctx;
515 if (NewCtx.contains(D)) {
516 NewCtx = ContextFactory.remove(NewCtx, D);
517 }
518 return NewCtx;
519 }
520
521 Context intersectContexts(Context C1, Context C2);
522 Context createReferenceContext(Context C);
523 void intersectBackEdge(Context C1, Context C2);
524
525 friend class VarMapBuilder;
526};
527
528
529// This has to be defined after LocalVariableMap.
530CFGBlockInfo CFGBlockInfo::getEmptyBlockInfo(Lockset::Factory &F,
531 LocalVariableMap &M) {
532 return CFGBlockInfo(F.getEmptyMap(), M.getEmptyContext());
533}
534
535
536/// Visitor which builds a LocalVariableMap
537class VarMapBuilder : public StmtVisitor<VarMapBuilder> {
538public:
539 LocalVariableMap* VMap;
540 LocalVariableMap::Context Ctx;
541
542 VarMapBuilder(LocalVariableMap *VM, LocalVariableMap::Context C)
543 : VMap(VM), Ctx(C) {}
544
545 void VisitDeclStmt(DeclStmt *S);
546 void VisitBinaryOperator(BinaryOperator *BO);
547};
548
549
550// Add new local variables to the variable map
551void VarMapBuilder::VisitDeclStmt(DeclStmt *S) {
552 bool modifiedCtx = false;
553 DeclGroupRef DGrp = S->getDeclGroup();
554 for (DeclGroupRef::iterator I = DGrp.begin(), E = DGrp.end(); I != E; ++I) {
555 if (VarDecl *VD = dyn_cast_or_null<VarDecl>(*I)) {
556 Expr *E = VD->getInit();
557
558 // Add local variables with trivial type to the variable map
559 QualType T = VD->getType();
560 if (T.isTrivialType(VD->getASTContext())) {
561 Ctx = VMap->addDefinition(VD, E, Ctx);
562 modifiedCtx = true;
563 }
564 }
565 }
566 if (modifiedCtx)
567 VMap->saveContext(S, Ctx);
568}
569
570// Update local variable definitions in variable map
571void VarMapBuilder::VisitBinaryOperator(BinaryOperator *BO) {
572 if (!BO->isAssignmentOp())
573 return;
574
575 Expr *LHSExp = BO->getLHS()->IgnoreParenCasts();
576
577 // Update the variable map and current context.
578 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(LHSExp)) {
579 ValueDecl *VDec = DRE->getDecl();
580 if (Ctx.lookup(VDec)) {
581 if (BO->getOpcode() == BO_Assign)
582 Ctx = VMap->updateDefinition(VDec, BO->getRHS(), Ctx);
583 else
584 // FIXME -- handle compound assignment operators
585 Ctx = VMap->clearDefinition(VDec, Ctx);
586 VMap->saveContext(BO, Ctx);
587 }
588 }
589}
590
591
592// Computes the intersection of two contexts. The intersection is the
593// set of variables which have the same definition in both contexts;
594// variables with different definitions are discarded.
595LocalVariableMap::Context
596LocalVariableMap::intersectContexts(Context C1, Context C2) {
597 Context Result = C1;
598 for (Context::iterator I = C1.begin(), E = C1.end(); I != E; ++I) {
599 NamedDecl *Dec = I.getKey();
600 unsigned i1 = I.getData();
601 const unsigned *i2 = C2.lookup(Dec);
602 if (!i2) // variable doesn't exist on second path
603 Result = removeDefinition(Dec, Result);
604 else if (*i2 != i1) // variable exists, but has different definition
605 Result = clearDefinition(Dec, Result);
606 }
607 return Result;
608}
609
610// For every variable in C, create a new variable that refers to the
611// definition in C. Return a new context that contains these new variables.
612// (We use this for a naive implementation of SSA on loop back-edges.)
613LocalVariableMap::Context LocalVariableMap::createReferenceContext(Context C) {
614 Context Result = getEmptyContext();
615 for (Context::iterator I = C.begin(), E = C.end(); I != E; ++I) {
616 NamedDecl *Dec = I.getKey();
617 unsigned i = I.getData();
618 Result = addReference(Dec, i, Result);
619 }
620 return Result;
621}
622
623// This routine also takes the intersection of C1 and C2, but it does so by
624// altering the VarDefinitions. C1 must be the result of an earlier call to
625// createReferenceContext.
626void LocalVariableMap::intersectBackEdge(Context C1, Context C2) {
627 for (Context::iterator I = C1.begin(), E = C1.end(); I != E; ++I) {
628 NamedDecl *Dec = I.getKey();
629 unsigned i1 = I.getData();
630 VarDefinition *VDef = &VarDefinitions[i1];
631 assert(VDef->isReference());
632
633 const unsigned *i2 = C2.lookup(Dec);
634 if (!i2 || (*i2 != i1))
635 VDef->Ref = 0; // Mark this variable as undefined
636 }
637}
638
639
640// Traverse the CFG in topological order, so all predecessors of a block
641// (excluding back-edges) are visited before the block itself. At
642// each point in the code, we calculate a Context, which holds the set of
643// variable definitions which are visible at that point in execution.
644// Visible variables are mapped to their definitions using an array that
645// contains all definitions.
646//
647// At join points in the CFG, the set is computed as the intersection of
648// the incoming sets along each edge, E.g.
649//
650// { Context | VarDefinitions }
651// int x = 0; { x -> x1 | x1 = 0 }
652// int y = 0; { x -> x1, y -> y1 | y1 = 0, x1 = 0 }
653// if (b) x = 1; { x -> x2, y -> y1 | x2 = 1, y1 = 0, ... }
654// else x = 2; { x -> x3, y -> y1 | x3 = 2, x2 = 1, ... }
655// ... { y -> y1 (x is unknown) | x3 = 2, x2 = 1, ... }
656//
657// This is essentially a simpler and more naive version of the standard SSA
658// algorithm. Those definitions that remain in the intersection are from blocks
659// that strictly dominate the current block. We do not bother to insert proper
660// phi nodes, because they are not used in our analysis; instead, wherever
661// a phi node would be required, we simply remove that definition from the
662// context (E.g. x above).
663//
664// The initial traversal does not capture back-edges, so those need to be
665// handled on a separate pass. Whenever the first pass encounters an
666// incoming back edge, it duplicates the context, creating new definitions
667// that refer back to the originals. (These correspond to places where SSA
668// might have to insert a phi node.) On the second pass, these definitions are
669// set to NULL if the the variable has changed on the back-edge (i.e. a phi
670// node was actually required.) E.g.
671//
672// { Context | VarDefinitions }
673// int x = 0, y = 0; { x -> x1, y -> y1 | y1 = 0, x1 = 0 }
674// while (b) { x -> x2, y -> y1 | [1st:] x2=x1; [2nd:] x2=NULL; }
675// x = x+1; { x -> x3, y -> y1 | x3 = x2 + 1, ... }
676// ... { y -> y1 | x3 = 2, x2 = 1, ... }
677//
678void LocalVariableMap::traverseCFG(CFG *CFGraph,
679 PostOrderCFGView *SortedGraph,
680 std::vector<CFGBlockInfo> &BlockInfo) {
681 PostOrderCFGView::CFGBlockSet VisitedBlocks(CFGraph);
682
683 CtxIndices.resize(CFGraph->getNumBlockIDs());
684
685 for (PostOrderCFGView::iterator I = SortedGraph->begin(),
686 E = SortedGraph->end(); I!= E; ++I) {
687 const CFGBlock *CurrBlock = *I;
688 int CurrBlockID = CurrBlock->getBlockID();
689 CFGBlockInfo *CurrBlockInfo = &BlockInfo[CurrBlockID];
690
691 VisitedBlocks.insert(CurrBlock);
692
693 // Calculate the entry context for the current block
694 bool HasBackEdges = false;
695 bool CtxInit = true;
696 for (CFGBlock::const_pred_iterator PI = CurrBlock->pred_begin(),
697 PE = CurrBlock->pred_end(); PI != PE; ++PI) {
698 // if *PI -> CurrBlock is a back edge, so skip it
699 if (*PI == 0 || !VisitedBlocks.alreadySet(*PI)) {
700 HasBackEdges = true;
701 continue;
702 }
703
704 int PrevBlockID = (*PI)->getBlockID();
705 CFGBlockInfo *PrevBlockInfo = &BlockInfo[PrevBlockID];
706
707 if (CtxInit) {
708 CurrBlockInfo->EntryContext = PrevBlockInfo->ExitContext;
709 CtxInit = false;
710 }
711 else {
712 CurrBlockInfo->EntryContext =
713 intersectContexts(CurrBlockInfo->EntryContext,
714 PrevBlockInfo->ExitContext);
715 }
716 }
717
718 // Duplicate the context if we have back-edges, so we can call
719 // intersectBackEdges later.
720 if (HasBackEdges)
721 CurrBlockInfo->EntryContext =
722 createReferenceContext(CurrBlockInfo->EntryContext);
723
724 // Create a starting context index for the current block
725 saveContext(0, CurrBlockInfo->EntryContext);
726 CurrBlockInfo->EntryIndex = getContextIndex();
727
728 // Visit all the statements in the basic block.
729 VarMapBuilder VMapBuilder(this, CurrBlockInfo->EntryContext);
730 for (CFGBlock::const_iterator BI = CurrBlock->begin(),
731 BE = CurrBlock->end(); BI != BE; ++BI) {
732 switch (BI->getKind()) {
733 case CFGElement::Statement: {
734 const CFGStmt *CS = cast<CFGStmt>(&*BI);
735 VMapBuilder.Visit(const_cast<Stmt*>(CS->getStmt()));
736 break;
737 }
738 default:
739 break;
740 }
741 }
742 CurrBlockInfo->ExitContext = VMapBuilder.Ctx;
743
744 // Mark variables on back edges as "unknown" if they've been changed.
745 for (CFGBlock::const_succ_iterator SI = CurrBlock->succ_begin(),
746 SE = CurrBlock->succ_end(); SI != SE; ++SI) {
747 // if CurrBlock -> *SI is *not* a back edge
748 if (*SI == 0 || !VisitedBlocks.alreadySet(*SI))
749 continue;
750
751 CFGBlock *FirstLoopBlock = *SI;
752 Context LoopBegin = BlockInfo[FirstLoopBlock->getBlockID()].EntryContext;
753 Context LoopEnd = CurrBlockInfo->ExitContext;
754 intersectBackEdge(LoopBegin, LoopEnd);
755 }
756 }
757
758 // Put an extra entry at the end of the indexed context array
759 unsigned exitID = CFGraph->getExit().getBlockID();
760 saveContext(0, BlockInfo[exitID].ExitContext);
761}
762
763
764/// \brief Class which implements the core thread safety analysis routines.
765class ThreadSafetyAnalyzer {
766 friend class BuildLockset;
767
768 ThreadSafetyHandler &Handler;
769 Lockset::Factory LocksetFactory;
770 LocalVariableMap LocalVarMap;
771
772public:
773 ThreadSafetyAnalyzer(ThreadSafetyHandler &H) : Handler(H) {}
774
775 Lockset intersectAndWarn(const Lockset LSet1, const Lockset LSet2,
776 LockErrorKind LEK);
777
778 Lockset addLock(Lockset &LSet, Expr *MutexExp, const NamedDecl *D,
779 LockKind LK, SourceLocation Loc);
780
781 void runAnalysis(AnalysisDeclContext &AC);
782};
783
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000784
785/// \brief We use this class to visit different types of expressions in
786/// CFGBlocks, and build up the lockset.
787/// An expression may cause us to add or remove locks from the lockset, or else
788/// output error messages related to missing locks.
789/// FIXME: In future, we may be able to not inherit from a visitor.
790class BuildLockset : public StmtVisitor<BuildLockset> {
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000791 friend class ThreadSafetyAnalyzer;
792
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000793 ThreadSafetyHandler &Handler;
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000794 Lockset::Factory &LocksetFactory;
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +0000795 LocalVariableMap &LocalVarMap;
796
797 Lockset LSet;
798 LocalVariableMap::Context LVarCtx;
799 unsigned CtxIndex;
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000800
801 // Helper functions
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000802 void addLock(const MutexID &Mutex, const LockData &LDat);
803 void removeLock(const MutexID &Mutex, SourceLocation UnlockLoc);
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000804
805 template <class AttrType>
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000806 void addLocksToSet(LockKind LK, AttrType *Attr,
807 Expr *Exp, NamedDecl *D, VarDecl *VD = 0);
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000808 void removeLocksFromSet(UnlockFunctionAttr *Attr,
809 Expr *Exp, NamedDecl* FunDecl);
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000810
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000811 const ValueDecl *getValueDecl(Expr *Exp);
812 void warnIfMutexNotHeld (const NamedDecl *D, Expr *Exp, AccessKind AK,
813 Expr *MutexExp, ProtectedOperationKind POK);
814 void checkAccess(Expr *Exp, AccessKind AK);
815 void checkDereference(Expr *Exp, AccessKind AK);
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000816 void handleCall(Expr *Exp, NamedDecl *D, VarDecl *VD = 0);
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000817
DeLesley Hutchinsb4fa4182012-01-06 19:16:50 +0000818 template <class AttrType>
819 void addTrylock(LockKind LK, AttrType *Attr, Expr *Exp, NamedDecl *FunDecl,
820 const CFGBlock* PredBlock, const CFGBlock *CurrBlock,
821 Expr *BrE, bool Neg);
822 CallExpr* getTrylockCallExpr(Stmt *Cond, LocalVariableMap::Context C,
823 bool &Negate);
824 void handleTrylock(Stmt *Cond, const CFGBlock* PredBlock,
825 const CFGBlock *CurrBlock);
826
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000827 /// \brief Returns true if the lockset contains a lock, regardless of whether
828 /// the lock is held exclusively or shared.
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000829 bool locksetContains(const MutexID &Lock) const {
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000830 return LSet.lookup(Lock);
831 }
832
833 /// \brief Returns true if the lockset contains a lock with the passed in
834 /// locktype.
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000835 bool locksetContains(const MutexID &Lock, LockKind KindRequested) const {
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000836 const LockData *LockHeld = LSet.lookup(Lock);
837 return (LockHeld && KindRequested == LockHeld->LKind);
838 }
839
840 /// \brief Returns true if the lockset contains a lock with at least the
841 /// passed in locktype. So for example, if we pass in LK_Shared, this function
842 /// returns true if the lock is held LK_Shared or LK_Exclusive. If we pass in
843 /// LK_Exclusive, this function returns true if the lock is held LK_Exclusive.
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000844 bool locksetContainsAtLeast(const MutexID &Lock,
845 LockKind KindRequested) const {
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000846 switch (KindRequested) {
847 case LK_Shared:
848 return locksetContains(Lock);
849 case LK_Exclusive:
850 return locksetContains(Lock, KindRequested);
851 }
Benjamin Kramerafc5b152011-09-10 21:52:04 +0000852 llvm_unreachable("Unknown LockKind");
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000853 }
854
855public:
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +0000856 BuildLockset(ThreadSafetyAnalyzer *analyzer, CFGBlockInfo &Info)
857 : StmtVisitor<BuildLockset>(),
858 Handler(analyzer->Handler),
859 LocksetFactory(analyzer->LocksetFactory),
860 LocalVarMap(analyzer->LocalVarMap),
861 LSet(Info.EntrySet),
862 LVarCtx(Info.EntryContext),
863 CtxIndex(Info.EntryIndex)
864 {}
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000865
866 void VisitUnaryOperator(UnaryOperator *UO);
867 void VisitBinaryOperator(BinaryOperator *BO);
868 void VisitCastExpr(CastExpr *CE);
DeLesley Hutchinsdf497822011-12-29 00:56:48 +0000869 void VisitCallExpr(CallExpr *Exp);
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +0000870 void VisitCXXConstructExpr(CXXConstructExpr *Exp);
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000871 void VisitDeclStmt(DeclStmt *S);
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000872};
873
874/// \brief Add a new lock to the lockset, warning if the lock is already there.
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000875/// \param Mutex -- the Mutex expression for the lock
876/// \param LDat -- the LockData for the lock
877void BuildLockset::addLock(const MutexID &Mutex, const LockData& LDat) {
878 // FIXME: deal with acquired before/after annotations.
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000879 // FIXME: Don't always warn when we have support for reentrant locks.
880 if (locksetContains(Mutex))
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000881 Handler.handleDoubleLock(Mutex.getName(), LDat.AcquireLoc);
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000882 else
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000883 LSet = LocksetFactory.add(LSet, Mutex, LDat);
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000884}
885
886/// \brief Remove a lock from the lockset, warning if the lock is not there.
887/// \param LockExp The lock expression corresponding to the lock to be removed
888/// \param UnlockLoc The source location of the unlock (only used in error msg)
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000889void BuildLockset::removeLock(const MutexID &Mutex, SourceLocation UnlockLoc) {
890 const LockData *LDat = LSet.lookup(Mutex);
891 if (!LDat)
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000892 Handler.handleUnmatchedUnlock(Mutex.getName(), UnlockLoc);
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000893 else {
894 // For scoped-lockable vars, remove the mutex associated with this var.
895 if (LDat->UnderlyingMutex.isValid())
896 removeLock(LDat->UnderlyingMutex, UnlockLoc);
897 LSet = LocksetFactory.remove(LSet, Mutex);
898 }
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000899}
900
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000901/// \brief This function, parameterized by an attribute type, is used to add a
902/// set of locks specified as attribute arguments to the lockset.
903template <typename AttrType>
904void BuildLockset::addLocksToSet(LockKind LK, AttrType *Attr,
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000905 Expr *Exp, NamedDecl* FunDecl, VarDecl *VD) {
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000906 typedef typename AttrType::args_iterator iterator_type;
907
908 SourceLocation ExpLocation = Exp->getExprLoc();
909
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000910 // Figure out if we're calling the constructor of scoped lockable class
911 bool isScopedVar = false;
912 if (VD) {
913 if (CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FunDecl)) {
914 CXXRecordDecl* PD = CD->getParent();
915 if (PD && PD->getAttr<ScopedLockableAttr>())
916 isScopedVar = true;
917 }
918 }
919
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000920 if (Attr->args_size() == 0) {
921 // The mutex held is the "this" object.
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000922 MutexID Mutex(0, Exp, FunDecl);
923 if (!Mutex.isValid())
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000924 MutexID::warnInvalidLock(Handler, 0, Exp, FunDecl);
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000925 else
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000926 addLock(Mutex, LockData(ExpLocation, LK));
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000927 return;
928 }
929
930 for (iterator_type I=Attr->args_begin(), E=Attr->args_end(); I != E; ++I) {
931 MutexID Mutex(*I, Exp, FunDecl);
932 if (!Mutex.isValid())
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000933 MutexID::warnInvalidLock(Handler, *I, Exp, FunDecl);
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000934 else {
935 addLock(Mutex, LockData(ExpLocation, LK));
936 if (isScopedVar) {
937 // For scoped lockable vars, map this var to its underlying mutex.
938 DeclRefExpr DRE(VD, VD->getType(), VK_LValue, VD->getLocation());
939 MutexID SMutex(&DRE, 0, 0);
940 addLock(SMutex, LockData(VD->getLocation(), LK, Mutex));
941 }
942 }
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000943 }
944}
945
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000946/// \brief This function removes a set of locks specified as attribute
947/// arguments from the lockset.
948void BuildLockset::removeLocksFromSet(UnlockFunctionAttr *Attr,
949 Expr *Exp, NamedDecl* FunDecl) {
950 SourceLocation ExpLocation;
951 if (Exp) ExpLocation = Exp->getExprLoc();
952
953 if (Attr->args_size() == 0) {
954 // The mutex held is the "this" object.
955 MutexID Mu(0, Exp, FunDecl);
956 if (!Mu.isValid())
957 MutexID::warnInvalidLock(Handler, 0, Exp, FunDecl);
958 else
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000959 removeLock(Mu, ExpLocation);
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000960 return;
961 }
962
963 for (UnlockFunctionAttr::args_iterator I = Attr->args_begin(),
964 E = Attr->args_end(); I != E; ++I) {
965 MutexID Mutex(*I, Exp, FunDecl);
966 if (!Mutex.isValid())
967 MutexID::warnInvalidLock(Handler, *I, Exp, FunDecl);
968 else
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000969 removeLock(Mutex, ExpLocation);
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000970 }
971}
972
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000973/// \brief Gets the value decl pointer from DeclRefExprs or MemberExprs
974const ValueDecl *BuildLockset::getValueDecl(Expr *Exp) {
975 if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Exp))
976 return DR->getDecl();
977
978 if (const MemberExpr *ME = dyn_cast<MemberExpr>(Exp))
979 return ME->getMemberDecl();
980
981 return 0;
982}
983
984/// \brief Warn if the LSet does not contain a lock sufficient to protect access
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000985/// of at least the passed in AccessKind.
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000986void BuildLockset::warnIfMutexNotHeld(const NamedDecl *D, Expr *Exp,
987 AccessKind AK, Expr *MutexExp,
988 ProtectedOperationKind POK) {
989 LockKind LK = getLockKindFromAccessKind(AK);
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000990
991 MutexID Mutex(MutexExp, Exp, D);
Caitlin Sadowski194418f2011-09-14 20:00:24 +0000992 if (!Mutex.isValid())
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000993 MutexID::warnInvalidLock(Handler, MutexExp, Exp, D);
Caitlin Sadowski194418f2011-09-14 20:00:24 +0000994 else if (!locksetContainsAtLeast(Mutex, LK))
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000995 Handler.handleMutexNotHeld(D, POK, Mutex.getName(), LK, Exp->getExprLoc());
996}
997
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000998/// \brief This method identifies variable dereferences and checks pt_guarded_by
999/// and pt_guarded_var annotations. Note that we only check these annotations
1000/// at the time a pointer is dereferenced.
1001/// FIXME: We need to check for other types of pointer dereferences
1002/// (e.g. [], ->) and deal with them here.
1003/// \param Exp An expression that has been read or written.
1004void BuildLockset::checkDereference(Expr *Exp, AccessKind AK) {
1005 UnaryOperator *UO = dyn_cast<UnaryOperator>(Exp);
1006 if (!UO || UO->getOpcode() != clang::UO_Deref)
1007 return;
1008 Exp = UO->getSubExpr()->IgnoreParenCasts();
1009
1010 const ValueDecl *D = getValueDecl(Exp);
1011 if(!D || !D->hasAttrs())
1012 return;
1013
1014 if (D->getAttr<PtGuardedVarAttr>() && LSet.isEmpty())
1015 Handler.handleNoMutexHeld(D, POK_VarDereference, AK, Exp->getExprLoc());
1016
1017 const AttrVec &ArgAttrs = D->getAttrs();
1018 for(unsigned i = 0, Size = ArgAttrs.size(); i < Size; ++i)
1019 if (PtGuardedByAttr *PGBAttr = dyn_cast<PtGuardedByAttr>(ArgAttrs[i]))
1020 warnIfMutexNotHeld(D, Exp, AK, PGBAttr->getArg(), POK_VarDereference);
1021}
1022
1023/// \brief Checks guarded_by and guarded_var attributes.
1024/// Whenever we identify an access (read or write) of a DeclRefExpr or
1025/// MemberExpr, we need to check whether there are any guarded_by or
1026/// guarded_var attributes, and make sure we hold the appropriate mutexes.
1027void BuildLockset::checkAccess(Expr *Exp, AccessKind AK) {
1028 const ValueDecl *D = getValueDecl(Exp);
1029 if(!D || !D->hasAttrs())
1030 return;
1031
1032 if (D->getAttr<GuardedVarAttr>() && LSet.isEmpty())
1033 Handler.handleNoMutexHeld(D, POK_VarAccess, AK, Exp->getExprLoc());
1034
1035 const AttrVec &ArgAttrs = D->getAttrs();
1036 for(unsigned i = 0, Size = ArgAttrs.size(); i < Size; ++i)
1037 if (GuardedByAttr *GBAttr = dyn_cast<GuardedByAttr>(ArgAttrs[i]))
1038 warnIfMutexNotHeld(D, Exp, AK, GBAttr->getArg(), POK_VarAccess);
1039}
1040
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +00001041/// \brief Process a function call, method call, constructor call,
1042/// or destructor call. This involves looking at the attributes on the
1043/// corresponding function/method/constructor/destructor, issuing warnings,
1044/// and updating the locksets accordingly.
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001045///
1046/// FIXME: For classes annotated with one of the guarded annotations, we need
1047/// to treat const method calls as reads and non-const method calls as writes,
1048/// and check that the appropriate locks are held. Non-const method calls with
1049/// the same signature as const method calls can be also treated as reads.
1050///
1051/// FIXME: We need to also visit CallExprs to catch/check global functions.
Caitlin Sadowski1748b122011-09-16 00:35:54 +00001052///
1053/// FIXME: Do not flag an error for member variables accessed in constructors/
1054/// destructors
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +00001055void BuildLockset::handleCall(Expr *Exp, NamedDecl *D, VarDecl *VD) {
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001056 AttrVec &ArgAttrs = D->getAttrs();
1057 for(unsigned i = 0; i < ArgAttrs.size(); ++i) {
1058 Attr *Attr = ArgAttrs[i];
1059 switch (Attr->getKind()) {
1060 // When we encounter an exclusive lock function, we need to add the lock
1061 // to our lockset with kind exclusive.
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001062 case attr::ExclusiveLockFunction: {
1063 ExclusiveLockFunctionAttr *A = cast<ExclusiveLockFunctionAttr>(Attr);
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +00001064 addLocksToSet(LK_Exclusive, A, Exp, D, VD);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001065 break;
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001066 }
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001067
1068 // When we encounter a shared lock function, we need to add the lock
1069 // to our lockset with kind shared.
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001070 case attr::SharedLockFunction: {
1071 SharedLockFunctionAttr *A = cast<SharedLockFunctionAttr>(Attr);
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +00001072 addLocksToSet(LK_Shared, A, Exp, D, VD);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001073 break;
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001074 }
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001075
1076 // When we encounter an unlock function, we need to remove unlocked
1077 // mutexes from the lockset, and flag a warning if they are not there.
1078 case attr::UnlockFunction: {
1079 UnlockFunctionAttr *UFAttr = cast<UnlockFunctionAttr>(Attr);
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +00001080 removeLocksFromSet(UFAttr, Exp, D);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001081 break;
1082 }
1083
1084 case attr::ExclusiveLocksRequired: {
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001085 ExclusiveLocksRequiredAttr *ELRAttr =
1086 cast<ExclusiveLocksRequiredAttr>(Attr);
1087
1088 for (ExclusiveLocksRequiredAttr::args_iterator
1089 I = ELRAttr->args_begin(), E = ELRAttr->args_end(); I != E; ++I)
1090 warnIfMutexNotHeld(D, Exp, AK_Written, *I, POK_FunctionCall);
1091 break;
1092 }
1093
1094 case attr::SharedLocksRequired: {
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001095 SharedLocksRequiredAttr *SLRAttr = cast<SharedLocksRequiredAttr>(Attr);
1096
1097 for (SharedLocksRequiredAttr::args_iterator I = SLRAttr->args_begin(),
1098 E = SLRAttr->args_end(); I != E; ++I)
1099 warnIfMutexNotHeld(D, Exp, AK_Read, *I, POK_FunctionCall);
1100 break;
1101 }
1102
1103 case attr::LocksExcluded: {
1104 LocksExcludedAttr *LEAttr = cast<LocksExcludedAttr>(Attr);
1105 for (LocksExcludedAttr::args_iterator I = LEAttr->args_begin(),
1106 E = LEAttr->args_end(); I != E; ++I) {
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001107 MutexID Mutex(*I, Exp, D);
Caitlin Sadowski194418f2011-09-14 20:00:24 +00001108 if (!Mutex.isValid())
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +00001109 MutexID::warnInvalidLock(Handler, *I, Exp, D);
Caitlin Sadowski194418f2011-09-14 20:00:24 +00001110 else if (locksetContains(Mutex))
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001111 Handler.handleFunExcludesLock(D->getName(), Mutex.getName(),
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +00001112 Exp->getExprLoc());
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001113 }
1114 break;
1115 }
1116
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001117 // Ignore other (non thread-safety) attributes
1118 default:
1119 break;
1120 }
1121 }
1122}
1123
DeLesley Hutchinsb4fa4182012-01-06 19:16:50 +00001124
1125/// \brief Add lock to set, if the current block is in the taken branch of a
1126/// trylock.
1127template <class AttrType>
1128void BuildLockset::addTrylock(LockKind LK, AttrType *Attr, Expr *Exp,
1129 NamedDecl *FunDecl, const CFGBlock *PredBlock,
1130 const CFGBlock *CurrBlock, Expr *BrE, bool Neg) {
1131 // Find out which branch has the lock
1132 bool branch = 0;
1133 if (CXXBoolLiteralExpr *BLE = dyn_cast_or_null<CXXBoolLiteralExpr>(BrE)) {
1134 branch = BLE->getValue();
1135 }
1136 else if (IntegerLiteral *ILE = dyn_cast_or_null<IntegerLiteral>(BrE)) {
1137 branch = ILE->getValue().getBoolValue();
1138 }
1139 int branchnum = branch ? 0 : 1;
1140 if (Neg) branchnum = !branchnum;
1141
1142 // If we've taken the trylock branch, then add the lock
1143 int i = 0;
1144 for (CFGBlock::const_succ_iterator SI = PredBlock->succ_begin(),
1145 SE = PredBlock->succ_end(); SI != SE && i < 2; ++SI, ++i) {
1146 if (*SI == CurrBlock && i == branchnum) {
1147 addLocksToSet(LK, Attr, Exp, FunDecl, 0);
1148 }
1149 }
1150}
1151
1152
1153// If Cond can be traced back to a function call, return the call expression.
1154// The negate variable should be called with false, and will be set to true
1155// if the function call is negated, e.g. if (!mu.tryLock(...))
1156CallExpr* BuildLockset::getTrylockCallExpr(Stmt *Cond,
1157 LocalVariableMap::Context C,
1158 bool &Negate) {
1159 if (!Cond)
1160 return 0;
1161
1162 if (CallExpr *CallExp = dyn_cast<CallExpr>(Cond)) {
1163 return CallExp;
1164 }
1165 else if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(Cond)) {
1166 return getTrylockCallExpr(CE->getSubExpr(), C, Negate);
1167 }
1168 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Cond)) {
1169 Expr *E = LocalVarMap.lookupExpr(DRE->getDecl(), C);
1170 return getTrylockCallExpr(E, C, Negate);
1171 }
1172 else if (UnaryOperator *UOP = dyn_cast<UnaryOperator>(Cond)) {
1173 if (UOP->getOpcode() == UO_LNot) {
1174 Negate = !Negate;
1175 return getTrylockCallExpr(UOP->getSubExpr(), C, Negate);
1176 }
1177 }
1178 // FIXME -- handle && and || as well.
1179 return NULL;
1180}
1181
1182
1183/// \brief Process a conditional branch from a previous block to the current
1184/// block, looking for trylock calls.
1185void BuildLockset::handleTrylock(Stmt *Cond, const CFGBlock *PredBlock,
1186 const CFGBlock *CurrBlock) {
1187 bool Negate = false;
1188 CallExpr *Exp = getTrylockCallExpr(Cond, LVarCtx, Negate);
1189 if (!Exp)
1190 return;
1191
1192 NamedDecl *FunDecl = dyn_cast_or_null<NamedDecl>(Exp->getCalleeDecl());
1193 if(!FunDecl || !FunDecl->hasAttrs())
1194 return;
1195
1196 // If the condition is a call to a Trylock function, then grab the attributes
1197 AttrVec &ArgAttrs = FunDecl->getAttrs();
1198 for (unsigned i = 0; i < ArgAttrs.size(); ++i) {
1199 Attr *Attr = ArgAttrs[i];
1200 switch (Attr->getKind()) {
1201 case attr::ExclusiveTrylockFunction: {
1202 ExclusiveTrylockFunctionAttr *A =
1203 cast<ExclusiveTrylockFunctionAttr>(Attr);
1204 addTrylock(LK_Exclusive, A, Exp, FunDecl, PredBlock, CurrBlock,
1205 A->getSuccessValue(), Negate);
1206 break;
1207 }
1208 case attr::SharedTrylockFunction: {
1209 SharedTrylockFunctionAttr *A =
1210 cast<SharedTrylockFunctionAttr>(Attr);
1211 addTrylock(LK_Shared, A, Exp, FunDecl, PredBlock, CurrBlock,
1212 A->getSuccessValue(), Negate);
1213 break;
1214 }
1215 default:
1216 break;
1217 }
1218 }
1219}
1220
1221
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +00001222/// \brief For unary operations which read and write a variable, we need to
1223/// check whether we hold any required mutexes. Reads are checked in
1224/// VisitCastExpr.
1225void BuildLockset::VisitUnaryOperator(UnaryOperator *UO) {
1226 switch (UO->getOpcode()) {
1227 case clang::UO_PostDec:
1228 case clang::UO_PostInc:
1229 case clang::UO_PreDec:
1230 case clang::UO_PreInc: {
1231 Expr *SubExp = UO->getSubExpr()->IgnoreParenCasts();
1232 checkAccess(SubExp, AK_Written);
1233 checkDereference(SubExp, AK_Written);
1234 break;
1235 }
1236 default:
1237 break;
1238 }
1239}
1240
1241/// For binary operations which assign to a variable (writes), we need to check
1242/// whether we hold any required mutexes.
1243/// FIXME: Deal with non-primitive types.
1244void BuildLockset::VisitBinaryOperator(BinaryOperator *BO) {
1245 if (!BO->isAssignmentOp())
1246 return;
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001247
1248 // adjust the context
1249 LVarCtx = LocalVarMap.getNextContext(CtxIndex, BO, LVarCtx);
1250
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +00001251 Expr *LHSExp = BO->getLHS()->IgnoreParenCasts();
1252 checkAccess(LHSExp, AK_Written);
1253 checkDereference(LHSExp, AK_Written);
1254}
1255
1256/// Whenever we do an LValue to Rvalue cast, we are reading a variable and
1257/// need to ensure we hold any required mutexes.
1258/// FIXME: Deal with non-primitive types.
1259void BuildLockset::VisitCastExpr(CastExpr *CE) {
1260 if (CE->getCastKind() != CK_LValueToRValue)
1261 return;
1262 Expr *SubExp = CE->getSubExpr()->IgnoreParenCasts();
1263 checkAccess(SubExp, AK_Read);
1264 checkDereference(SubExp, AK_Read);
1265}
1266
1267
DeLesley Hutchinsdf497822011-12-29 00:56:48 +00001268void BuildLockset::VisitCallExpr(CallExpr *Exp) {
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +00001269 NamedDecl *D = dyn_cast_or_null<NamedDecl>(Exp->getCalleeDecl());
1270 if(!D || !D->hasAttrs())
1271 return;
1272 handleCall(Exp, D);
1273}
1274
1275void BuildLockset::VisitCXXConstructExpr(CXXConstructExpr *Exp) {
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +00001276 // FIXME -- only handles constructors in DeclStmt below.
1277}
1278
1279void BuildLockset::VisitDeclStmt(DeclStmt *S) {
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001280 // adjust the context
1281 LVarCtx = LocalVarMap.getNextContext(CtxIndex, S, LVarCtx);
1282
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +00001283 DeclGroupRef DGrp = S->getDeclGroup();
1284 for (DeclGroupRef::iterator I = DGrp.begin(), E = DGrp.end(); I != E; ++I) {
1285 Decl *D = *I;
1286 if (VarDecl *VD = dyn_cast_or_null<VarDecl>(D)) {
1287 Expr *E = VD->getInit();
1288 if (CXXConstructExpr *CE = dyn_cast_or_null<CXXConstructExpr>(E)) {
1289 NamedDecl *CtorD = dyn_cast_or_null<NamedDecl>(CE->getConstructor());
1290 if (!CtorD || !CtorD->hasAttrs())
1291 return;
1292 handleCall(CE, CtorD, VD);
1293 }
1294 }
1295 }
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +00001296}
1297
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001298
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +00001299/// \brief Compute the intersection of two locksets and issue warnings for any
1300/// locks in the symmetric difference.
1301///
1302/// This function is used at a merge point in the CFG when comparing the lockset
1303/// of each branch being merged. For example, given the following sequence:
1304/// A; if () then B; else C; D; we need to check that the lockset after B and C
1305/// are the same. In the event of a difference, we use the intersection of these
1306/// two locksets at the start of D.
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001307Lockset ThreadSafetyAnalyzer::intersectAndWarn(const Lockset LSet1,
1308 const Lockset LSet2,
1309 LockErrorKind LEK) {
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +00001310 Lockset Intersection = LSet1;
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001311 for (Lockset::iterator I = LSet2.begin(), E = LSet2.end(); I != E; ++I) {
1312 const MutexID &LSet2Mutex = I.getKey();
1313 const LockData &LSet2LockData = I.getData();
1314 if (const LockData *LD = LSet1.lookup(LSet2Mutex)) {
1315 if (LD->LKind != LSet2LockData.LKind) {
1316 Handler.handleExclusiveAndShared(LSet2Mutex.getName(),
1317 LSet2LockData.AcquireLoc,
1318 LD->AcquireLoc);
1319 if (LD->LKind != LK_Exclusive)
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001320 Intersection = LocksetFactory.add(Intersection, LSet2Mutex,
1321 LSet2LockData);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001322 }
1323 } else {
1324 Handler.handleMutexHeldEndOfScope(LSet2Mutex.getName(),
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +00001325 LSet2LockData.AcquireLoc, LEK);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001326 }
1327 }
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001328
1329 for (Lockset::iterator I = LSet1.begin(), E = LSet1.end(); I != E; ++I) {
1330 if (!LSet2.contains(I.getKey())) {
1331 const MutexID &Mutex = I.getKey();
1332 const LockData &MissingLock = I.getData();
1333 Handler.handleMutexHeldEndOfScope(Mutex.getName(),
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +00001334 MissingLock.AcquireLoc, LEK);
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001335 Intersection = LocksetFactory.remove(Intersection, Mutex);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001336 }
1337 }
1338 return Intersection;
1339}
1340
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001341Lockset ThreadSafetyAnalyzer::addLock(Lockset &LSet, Expr *MutexExp,
1342 const NamedDecl *D,
1343 LockKind LK, SourceLocation Loc) {
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001344 MutexID Mutex(MutexExp, 0, D);
Caitlin Sadowskicb967512011-09-15 17:43:08 +00001345 if (!Mutex.isValid()) {
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +00001346 MutexID::warnInvalidLock(Handler, MutexExp, 0, D);
Caitlin Sadowskicb967512011-09-15 17:43:08 +00001347 return LSet;
1348 }
1349 LockData NewLock(Loc, LK);
1350 return LocksetFactory.add(LSet, Mutex, NewLock);
1351}
1352
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001353/// \brief Check a function's CFG for thread-safety violations.
1354///
1355/// We traverse the blocks in the CFG, compute the set of mutexes that are held
1356/// at the end of each block, and issue warnings for thread safety violations.
1357/// Each block in the CFG is traversed exactly once.
Ted Kremenek1d26f482011-10-24 01:32:45 +00001358void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) {
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001359 CFG *CFGraph = AC.getCFG();
1360 if (!CFGraph) return;
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001361 const NamedDecl *D = dyn_cast_or_null<NamedDecl>(AC.getDecl());
1362
1363 if (!D)
1364 return; // Ignore anonymous functions for now.
1365 if (D->getAttr<NoThreadSafetyAnalysisAttr>())
1366 return;
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001367
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001368 std::vector<CFGBlockInfo> BlockInfo(CFGraph->getNumBlockIDs(),
1369 CFGBlockInfo::getEmptyBlockInfo(LocksetFactory, LocalVarMap));
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001370
1371 // We need to explore the CFG via a "topological" ordering.
1372 // That way, we will be guaranteed to have information about required
1373 // predecessor locksets when exploring a new block.
Ted Kremenek439ed162011-10-22 02:14:27 +00001374 PostOrderCFGView *SortedGraph = AC.getAnalysis<PostOrderCFGView>();
1375 PostOrderCFGView::CFGBlockSet VisitedBlocks(CFGraph);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001376
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001377 // Compute SSA names for local variables
1378 LocalVarMap.traverseCFG(CFGraph, SortedGraph, BlockInfo);
1379
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001380 // Add locks from exclusive_locks_required and shared_locks_required
1381 // to initial lockset.
Ted Kremenek439ed162011-10-22 02:14:27 +00001382 if (!SortedGraph->empty() && D->hasAttrs()) {
1383 const CFGBlock *FirstBlock = *SortedGraph->begin();
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001384 Lockset &InitialLockset = BlockInfo[FirstBlock->getBlockID()].EntrySet;
Caitlin Sadowskicb967512011-09-15 17:43:08 +00001385 const AttrVec &ArgAttrs = D->getAttrs();
1386 for(unsigned i = 0; i < ArgAttrs.size(); ++i) {
1387 Attr *Attr = ArgAttrs[i];
Caitlin Sadowski1748b122011-09-16 00:35:54 +00001388 SourceLocation AttrLoc = Attr->getLocation();
Caitlin Sadowskicb967512011-09-15 17:43:08 +00001389 if (SharedLocksRequiredAttr *SLRAttr
1390 = dyn_cast<SharedLocksRequiredAttr>(Attr)) {
1391 for (SharedLocksRequiredAttr::args_iterator
1392 SLRIter = SLRAttr->args_begin(),
1393 SLREnd = SLRAttr->args_end(); SLRIter != SLREnd; ++SLRIter)
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001394 InitialLockset = addLock(InitialLockset,
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001395 *SLRIter, D, LK_Shared,
Caitlin Sadowski1748b122011-09-16 00:35:54 +00001396 AttrLoc);
Caitlin Sadowskicb967512011-09-15 17:43:08 +00001397 } else if (ExclusiveLocksRequiredAttr *ELRAttr
1398 = dyn_cast<ExclusiveLocksRequiredAttr>(Attr)) {
1399 for (ExclusiveLocksRequiredAttr::args_iterator
1400 ELRIter = ELRAttr->args_begin(),
1401 ELREnd = ELRAttr->args_end(); ELRIter != ELREnd; ++ELRIter)
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001402 InitialLockset = addLock(InitialLockset,
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001403 *ELRIter, D, LK_Exclusive,
Caitlin Sadowski1748b122011-09-16 00:35:54 +00001404 AttrLoc);
Caitlin Sadowskicb967512011-09-15 17:43:08 +00001405 }
1406 }
1407 }
1408
Ted Kremenek439ed162011-10-22 02:14:27 +00001409 for (PostOrderCFGView::iterator I = SortedGraph->begin(),
1410 E = SortedGraph->end(); I!= E; ++I) {
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001411 const CFGBlock *CurrBlock = *I;
1412 int CurrBlockID = CurrBlock->getBlockID();
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001413 CFGBlockInfo *CurrBlockInfo = &BlockInfo[CurrBlockID];
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001414
1415 // Use the default initial lockset in case there are no predecessors.
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001416 VisitedBlocks.insert(CurrBlock);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001417
1418 // Iterate through the predecessor blocks and warn if the lockset for all
1419 // predecessors is not the same. We take the entry lockset of the current
1420 // block to be the intersection of all previous locksets.
1421 // FIXME: By keeping the intersection, we may output more errors in future
1422 // for a lock which is not in the intersection, but was in the union. We
1423 // may want to also keep the union in future. As an example, let's say
1424 // the intersection contains Mutex L, and the union contains L and M.
1425 // Later we unlock M. At this point, we would output an error because we
1426 // never locked M; although the real error is probably that we forgot to
1427 // lock M on all code paths. Conversely, let's say that later we lock M.
1428 // In this case, we should compare against the intersection instead of the
1429 // union because the real error is probably that we forgot to unlock M on
1430 // all code paths.
1431 bool LocksetInitialized = false;
1432 for (CFGBlock::const_pred_iterator PI = CurrBlock->pred_begin(),
1433 PE = CurrBlock->pred_end(); PI != PE; ++PI) {
1434
1435 // if *PI -> CurrBlock is a back edge
1436 if (*PI == 0 || !VisitedBlocks.alreadySet(*PI))
1437 continue;
1438
1439 int PrevBlockID = (*PI)->getBlockID();
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001440 CFGBlockInfo *PrevBlockInfo = &BlockInfo[PrevBlockID];
1441
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001442 if (!LocksetInitialized) {
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001443 CurrBlockInfo->EntrySet = PrevBlockInfo->ExitSet;
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001444 LocksetInitialized = true;
1445 } else {
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001446 CurrBlockInfo->EntrySet =
1447 intersectAndWarn(CurrBlockInfo->EntrySet, PrevBlockInfo->ExitSet,
1448 LEK_LockedSomePredecessors);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001449 }
1450 }
1451
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001452 BuildLockset LocksetBuilder(this, *CurrBlockInfo);
DeLesley Hutchinsb4fa4182012-01-06 19:16:50 +00001453 CFGBlock::const_pred_iterator PI = CurrBlock->pred_begin(),
1454 PE = CurrBlock->pred_end();
1455 if (PI != PE) {
1456 // If the predecessor ended in a branch, then process any trylocks.
1457 // FIXME -- check to make sure there's only one predecessor.
1458 if (Stmt *TCE = (*PI)->getTerminatorCondition()) {
1459 LocksetBuilder.handleTrylock(TCE, *PI, CurrBlock);
1460 }
1461 }
1462
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001463 // Visit all the statements in the basic block.
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001464 for (CFGBlock::const_iterator BI = CurrBlock->begin(),
1465 BE = CurrBlock->end(); BI != BE; ++BI) {
DeLesley Hutchins6db51f72011-10-21 20:51:27 +00001466 switch (BI->getKind()) {
1467 case CFGElement::Statement: {
1468 const CFGStmt *CS = cast<CFGStmt>(&*BI);
1469 LocksetBuilder.Visit(const_cast<Stmt*>(CS->getStmt()));
1470 break;
1471 }
1472 // Ignore BaseDtor, MemberDtor, and TemporaryDtor for now.
1473 case CFGElement::AutomaticObjectDtor: {
1474 const CFGAutomaticObjDtor *AD = cast<CFGAutomaticObjDtor>(&*BI);
1475 CXXDestructorDecl *DD = const_cast<CXXDestructorDecl*>(
1476 AD->getDestructorDecl(AC.getASTContext()));
1477 if (!DD->hasAttrs())
1478 break;
1479
1480 // Create a dummy expression,
1481 VarDecl *VD = const_cast<VarDecl*>(AD->getVarDecl());
1482 DeclRefExpr DRE(VD, VD->getType(), VK_LValue,
1483 AD->getTriggerStmt()->getLocEnd());
1484 LocksetBuilder.handleCall(&DRE, DD);
1485 break;
1486 }
1487 default:
1488 break;
1489 }
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001490 }
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001491 CurrBlockInfo->ExitSet = LocksetBuilder.LSet;
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001492
1493 // For every back edge from CurrBlock (the end of the loop) to another block
1494 // (FirstLoopBlock) we need to check that the Lockset of Block is equal to
1495 // the one held at the beginning of FirstLoopBlock. We can look up the
1496 // Lockset held at the beginning of FirstLoopBlock in the EntryLockSets map.
1497 for (CFGBlock::const_succ_iterator SI = CurrBlock->succ_begin(),
1498 SE = CurrBlock->succ_end(); SI != SE; ++SI) {
1499
1500 // if CurrBlock -> *SI is *not* a back edge
1501 if (*SI == 0 || !VisitedBlocks.alreadySet(*SI))
1502 continue;
1503
1504 CFGBlock *FirstLoopBlock = *SI;
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001505 Lockset PreLoop = BlockInfo[FirstLoopBlock->getBlockID()].EntrySet;
1506 Lockset LoopEnd = BlockInfo[CurrBlockID].ExitSet;
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001507 intersectAndWarn(LoopEnd, PreLoop, LEK_LockedSomeLoopIterations);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001508 }
1509 }
1510
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001511 Lockset InitialLockset = BlockInfo[CFGraph->getEntry().getBlockID()].EntrySet;
1512 Lockset FinalLockset = BlockInfo[CFGraph->getExit().getBlockID()].ExitSet;
Caitlin Sadowski1748b122011-09-16 00:35:54 +00001513
1514 // FIXME: Should we call this function for all blocks which exit the function?
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001515 intersectAndWarn(InitialLockset, FinalLockset, LEK_LockedAtEndOfFunction);
1516}
1517
1518} // end anonymous namespace
1519
1520
1521namespace clang {
1522namespace thread_safety {
1523
1524/// \brief Check a function's CFG for thread-safety violations.
1525///
1526/// We traverse the blocks in the CFG, compute the set of mutexes that are held
1527/// at the end of each block, and issue warnings for thread safety violations.
1528/// Each block in the CFG is traversed exactly once.
Ted Kremenek1d26f482011-10-24 01:32:45 +00001529void runThreadSafetyAnalysis(AnalysisDeclContext &AC,
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001530 ThreadSafetyHandler &Handler) {
1531 ThreadSafetyAnalyzer Analyzer(Handler);
1532 Analyzer.runAnalysis(AC);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001533}
1534
1535/// \brief Helper function that returns a LockKind required for the given level
1536/// of access.
1537LockKind getLockKindFromAccessKind(AccessKind AK) {
1538 switch (AK) {
1539 case AK_Read :
1540 return LK_Shared;
1541 case AK_Written :
1542 return LK_Exclusive;
1543 }
Benjamin Kramerafc5b152011-09-10 21:52:04 +00001544 llvm_unreachable("Unknown AccessKind");
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001545}
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001546
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001547}} // end namespace clang::thread_safety