blob: caab66d2eeda4d667f18165509bdb33bc8ad8435 [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 Hutchins81216392011-10-17 21:38:02 +000091 void buildMutexID(Expr *Exp, Expr *Parent, int NumArgs,
92 const NamedDecl **FunArgDecls, 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)) {
DeLesley Hutchins81216392011-10-17 21:38:02 +000099 if (FunArgDecls) {
100 // Substitute call arguments for references to function parameters
101 for (int i = 0; i < NumArgs; ++i) {
102 if (DRE->getDecl() == FunArgDecls[i]) {
103 buildMutexID(FunArgs[i], 0, 0, 0, 0);
104 return;
105 }
106 }
107 }
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000108 NamedDecl *ND = cast<NamedDecl>(DRE->getDecl()->getCanonicalDecl());
109 DeclSeq.push_back(ND);
110 } else if (MemberExpr *ME = dyn_cast<MemberExpr>(Exp)) {
111 NamedDecl *ND = ME->getMemberDecl();
112 DeclSeq.push_back(ND);
DeLesley Hutchins81216392011-10-17 21:38:02 +0000113 buildMutexID(ME->getBase(), Parent, NumArgs, FunArgDecls, FunArgs);
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000114 } else if (isa<CXXThisExpr>(Exp)) {
Caitlin Sadowski194418f2011-09-14 20:00:24 +0000115 if (Parent)
DeLesley Hutchins81216392011-10-17 21:38:02 +0000116 buildMutexID(Parent, 0, 0, 0, 0);
Caitlin Sadowski194418f2011-09-14 20:00:24 +0000117 else
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000118 return; // mutexID is still valid in this case
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +0000119 } else if (UnaryOperator *UOE = dyn_cast<UnaryOperator>(Exp))
120 buildMutexID(UOE->getSubExpr(), Parent, NumArgs, FunArgDecls, FunArgs);
121 else if (CastExpr *CE = dyn_cast<CastExpr>(Exp))
DeLesley Hutchins81216392011-10-17 21:38:02 +0000122 buildMutexID(CE->getSubExpr(), Parent, NumArgs, FunArgDecls, FunArgs);
Caitlin Sadowski99107eb2011-09-09 16:21:55 +0000123 else
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000124 DeclSeq.clear(); // Mark as invalid lock expression.
125 }
126
127 /// \brief Construct a MutexID from an expression.
128 /// \param MutexExp The original mutex expression within an attribute
129 /// \param DeclExp An expression involving the Decl on which the attribute
130 /// occurs.
131 /// \param D The declaration to which the lock/unlock attribute is attached.
132 void buildMutexIDFromExp(Expr *MutexExp, Expr *DeclExp, const NamedDecl *D) {
133 Expr *Parent = 0;
DeLesley Hutchins81216392011-10-17 21:38:02 +0000134 unsigned NumArgs = 0;
135 Expr **FunArgs = 0;
136 SmallVector<const NamedDecl*, 8> FunArgDecls;
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000137
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000138 // If we are processing a raw attribute expression, with no substitutions.
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000139 if (DeclExp == 0) {
DeLesley Hutchins81216392011-10-17 21:38:02 +0000140 buildMutexID(MutexExp, 0, 0, 0, 0);
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000141 return;
142 }
143
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +0000144 // Examine DeclExp to find Parent and FunArgs, which are used to substitute
145 // for formal parameters when we call buildMutexID later.
DeLesley Hutchins81216392011-10-17 21:38:02 +0000146 if (MemberExpr *ME = dyn_cast<MemberExpr>(DeclExp)) {
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000147 Parent = ME->getBase();
DeLesley Hutchins81216392011-10-17 21:38:02 +0000148 } else if (CXXMemberCallExpr *CE = dyn_cast<CXXMemberCallExpr>(DeclExp)) {
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000149 Parent = CE->getImplicitObjectArgument();
DeLesley Hutchins81216392011-10-17 21:38:02 +0000150 NumArgs = CE->getNumArgs();
151 FunArgs = CE->getArgs();
DeLesley Hutchinsdf497822011-12-29 00:56:48 +0000152 } else if (CallExpr *CE = dyn_cast<CallExpr>(DeclExp)) {
153 NumArgs = CE->getNumArgs();
154 FunArgs = CE->getArgs();
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +0000155 } else if (CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(DeclExp)) {
156 Parent = 0; // FIXME -- get the parent from DeclStmt
157 NumArgs = CE->getNumArgs();
158 FunArgs = CE->getArgs();
DeLesley Hutchins6db51f72011-10-21 20:51:27 +0000159 } else if (D && isa<CXXDestructorDecl>(D)) {
160 // There's no such thing as a "destructor call" in the AST.
161 Parent = DeclExp;
DeLesley Hutchins81216392011-10-17 21:38:02 +0000162 }
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000163
164 // If the attribute has no arguments, then assume the argument is "this".
165 if (MutexExp == 0) {
DeLesley Hutchins81216392011-10-17 21:38:02 +0000166 buildMutexID(Parent, 0, 0, 0, 0);
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000167 return;
168 }
DeLesley Hutchins81216392011-10-17 21:38:02 +0000169
170 // FIXME: handle default arguments
171 if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
172 for (unsigned i = 0, ni = FD->getNumParams(); i < ni && i < NumArgs; ++i) {
173 FunArgDecls.push_back(FD->getParamDecl(i));
174 }
175 }
176 buildMutexID(MutexExp, Parent, NumArgs, &FunArgDecls.front(), FunArgs);
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000177 }
178
179public:
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000180 explicit MutexID(clang::Decl::EmptyShell e) {
181 DeclSeq.clear();
182 }
183
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000184 /// \param MutexExp The original mutex expression within an attribute
185 /// \param DeclExp An expression involving the Decl on which the attribute
186 /// occurs.
187 /// \param D The declaration to which the lock/unlock attribute is attached.
188 /// Caller must check isValid() after construction.
189 MutexID(Expr* MutexExp, Expr *DeclExp, const NamedDecl* D) {
190 buildMutexIDFromExp(MutexExp, DeclExp, D);
Caitlin Sadowski194418f2011-09-14 20:00:24 +0000191 }
192
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000193 /// Return true if this is a valid decl sequence.
194 /// Caller must call this by hand after construction to handle errors.
Caitlin Sadowski194418f2011-09-14 20:00:24 +0000195 bool isValid() const {
196 return !DeclSeq.empty();
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000197 }
198
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000199 /// Issue a warning about an invalid lock expression
200 static void warnInvalidLock(ThreadSafetyHandler &Handler, Expr* MutexExp,
201 Expr *DeclExp, const NamedDecl* D) {
202 SourceLocation Loc;
203 if (DeclExp)
204 Loc = DeclExp->getExprLoc();
205
206 // FIXME: add a note about the attribute location in MutexExp or D
207 if (Loc.isValid())
208 Handler.handleInvalidLockExp(Loc);
209 }
210
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000211 bool operator==(const MutexID &other) const {
212 return DeclSeq == other.DeclSeq;
213 }
214
215 bool operator!=(const MutexID &other) const {
216 return !(*this == other);
217 }
218
219 // SmallVector overloads Operator< to do lexicographic ordering. Note that
220 // we use pointer equality (and <) to compare NamedDecls. This means the order
221 // of MutexIDs in a lockset is nondeterministic. In order to output
222 // diagnostics in a deterministic ordering, we must order all diagnostics to
223 // output by SourceLocation when iterating through this lockset.
224 bool operator<(const MutexID &other) const {
225 return DeclSeq < other.DeclSeq;
226 }
227
228 /// \brief Returns the name of the first Decl in the list for a given MutexID;
229 /// e.g. the lock expression foo.bar() has name "bar".
230 /// The caret will point unambiguously to the lock expression, so using this
231 /// name in diagnostics is a way to get simple, and consistent, mutex names.
232 /// We do not want to output the entire expression text for security reasons.
233 StringRef getName() const {
Caitlin Sadowski194418f2011-09-14 20:00:24 +0000234 assert(isValid());
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000235 return DeclSeq.front()->getName();
236 }
237
238 void Profile(llvm::FoldingSetNodeID &ID) const {
239 for (SmallVectorImpl<NamedDecl*>::const_iterator I = DeclSeq.begin(),
240 E = DeclSeq.end(); I != E; ++I) {
241 ID.AddPointer(*I);
242 }
243 }
244};
245
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000246
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000247/// \brief This is a helper class that stores info about the most recent
248/// accquire of a Lock.
249///
250/// The main body of the analysis maps MutexIDs to LockDatas.
251struct LockData {
252 SourceLocation AcquireLoc;
253
254 /// \brief LKind stores whether a lock is held shared or exclusively.
255 /// Note that this analysis does not currently support either re-entrant
256 /// locking or lock "upgrading" and "downgrading" between exclusive and
257 /// shared.
258 ///
259 /// FIXME: add support for re-entrant locking and lock up/downgrading
260 LockKind LKind;
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000261 MutexID UnderlyingMutex; // for ScopedLockable objects
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000262
263 LockData(SourceLocation AcquireLoc, LockKind LKind)
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000264 : AcquireLoc(AcquireLoc), LKind(LKind), UnderlyingMutex(Decl::EmptyShell())
265 {}
266
267 LockData(SourceLocation AcquireLoc, LockKind LKind, const MutexID &Mu)
268 : AcquireLoc(AcquireLoc), LKind(LKind), UnderlyingMutex(Mu) {}
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000269
270 bool operator==(const LockData &other) const {
271 return AcquireLoc == other.AcquireLoc && LKind == other.LKind;
272 }
273
274 bool operator!=(const LockData &other) const {
275 return !(*this == other);
276 }
277
278 void Profile(llvm::FoldingSetNodeID &ID) const {
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000279 ID.AddInteger(AcquireLoc.getRawEncoding());
280 ID.AddInteger(LKind);
281 }
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000282};
283
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000284
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000285/// A Lockset maps each MutexID (defined above) to information about how it has
286/// been locked.
287typedef llvm::ImmutableMap<MutexID, LockData> Lockset;
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +0000288typedef llvm::ImmutableMap<NamedDecl*, unsigned> LocalVarContext;
289
290class LocalVariableMap;
291
292
293/// CFGBlockInfo is a struct which contains all the information that is
294/// maintained for each block in the CFG. See LocalVariableMap for more
295/// information about the contexts.
296struct CFGBlockInfo {
297 Lockset EntrySet; // Lockset held at entry to block
298 Lockset ExitSet; // Lockset held at exit from block
299 LocalVarContext EntryContext; // Context held at entry to block
300 LocalVarContext ExitContext; // Context held at exit from block
301 unsigned EntryIndex; // Used to replay contexts later
302
303private:
304 CFGBlockInfo(Lockset EmptySet, LocalVarContext EmptyCtx)
305 : EntrySet(EmptySet), ExitSet(EmptySet),
306 EntryContext(EmptyCtx), ExitContext(EmptyCtx)
307 { }
308
309public:
310 static CFGBlockInfo getEmptyBlockInfo(Lockset::Factory &F,
311 LocalVariableMap &M);
312};
313
314
315
316// A LocalVariableMap maintains a map from local variables to their currently
317// valid definitions. It provides SSA-like functionality when traversing the
318// CFG. Like SSA, each definition or assignment to a variable is assigned a
319// unique name (an integer), which acts as the SSA name for that definition.
320// The total set of names is shared among all CFG basic blocks.
321// Unlike SSA, we do not rewrite expressions to replace local variables declrefs
322// with their SSA-names. Instead, we compute a Context for each point in the
323// code, which maps local variables to the appropriate SSA-name. This map
324// changes with each assignment.
325//
326// The map is computed in a single pass over the CFG. Subsequent analyses can
327// then query the map to find the appropriate Context for a statement, and use
328// that Context to look up the definitions of variables.
329class LocalVariableMap {
330public:
331 typedef LocalVarContext Context;
332
333 /// A VarDefinition consists of an expression, representing the value of the
334 /// variable, along with the context in which that expression should be
335 /// interpreted. A reference VarDefinition does not itself contain this
336 /// information, but instead contains a pointer to a previous VarDefinition.
337 struct VarDefinition {
338 public:
339 friend class LocalVariableMap;
340
341 NamedDecl *Dec; // The original declaration for this variable.
342 Expr *Exp; // The expression for this variable, OR
343 unsigned Ref; // Reference to another VarDefinition
344 Context Ctx; // The map with which Exp should be interpreted.
345
346 bool isReference() { return !Exp; }
347
348 private:
349 // Create ordinary variable definition
350 VarDefinition(NamedDecl *D, Expr *E, Context C)
351 : Dec(D), Exp(E), Ref(0), Ctx(C)
352 { }
353
354 // Create reference to previous definition
355 VarDefinition(NamedDecl *D, unsigned R, Context C)
356 : Dec(D), Exp(0), Ref(R), Ctx(C)
357 { }
358 };
359
360private:
361 Context::Factory ContextFactory;
362 std::vector<VarDefinition> VarDefinitions;
363 std::vector<unsigned> CtxIndices;
364 std::vector<std::pair<Stmt*, Context> > SavedContexts;
365
366public:
367 LocalVariableMap() {
368 // index 0 is a placeholder for undefined variables (aka phi-nodes).
369 VarDefinitions.push_back(VarDefinition(0, 0u, getEmptyContext()));
370 }
371
372 /// Look up a definition, within the given context.
373 const VarDefinition* lookup(NamedDecl *D, Context Ctx) {
374 const unsigned *i = Ctx.lookup(D);
375 if (!i)
376 return 0;
377 assert(*i < VarDefinitions.size());
378 return &VarDefinitions[*i];
379 }
380
381 /// Look up the definition for D within the given context. Returns
382 /// NULL if the expression is not statically known.
383 Expr* lookupExpr(NamedDecl *D, Context Ctx) {
384 const unsigned *P = Ctx.lookup(D);
385 if (!P)
386 return 0;
387
388 unsigned i = *P;
389 while (i > 0) {
390 if (VarDefinitions[i].Exp)
391 return VarDefinitions[i].Exp;
392 i = VarDefinitions[i].Ref;
393 }
394 return 0;
395 }
396
397 Context getEmptyContext() { return ContextFactory.getEmptyMap(); }
398
399 /// Return the next context after processing S. This function is used by
400 /// clients of the class to get the appropriate context when traversing the
401 /// CFG. It must be called for every assignment or DeclStmt.
402 Context getNextContext(unsigned &CtxIndex, Stmt *S, Context C) {
403 if (SavedContexts[CtxIndex+1].first == S) {
404 CtxIndex++;
405 Context Result = SavedContexts[CtxIndex].second;
406 return Result;
407 }
408 return C;
409 }
410
411 void dumpVarDefinitionName(unsigned i) {
412 if (i == 0) {
413 llvm::errs() << "Undefined";
414 return;
415 }
416 NamedDecl *Dec = VarDefinitions[i].Dec;
417 if (!Dec) {
418 llvm::errs() << "<<NULL>>";
419 return;
420 }
421 Dec->printName(llvm::errs());
422 llvm::errs() << "." << i << " " << ((void*) Dec);
423 }
424
425 /// Dumps an ASCII representation of the variable map to llvm::errs()
426 void dump() {
427 for (unsigned i = 1, e = VarDefinitions.size(); i < e; ++i) {
428 Expr *Exp = VarDefinitions[i].Exp;
429 unsigned Ref = VarDefinitions[i].Ref;
430
431 dumpVarDefinitionName(i);
432 llvm::errs() << " = ";
433 if (Exp) Exp->dump();
434 else {
435 dumpVarDefinitionName(Ref);
436 llvm::errs() << "\n";
437 }
438 }
439 }
440
441 /// Dumps an ASCII representation of a Context to llvm::errs()
442 void dumpContext(Context C) {
443 for (Context::iterator I = C.begin(), E = C.end(); I != E; ++I) {
444 NamedDecl *D = I.getKey();
445 D->printName(llvm::errs());
446 const unsigned *i = C.lookup(D);
447 llvm::errs() << " -> ";
448 dumpVarDefinitionName(*i);
449 llvm::errs() << "\n";
450 }
451 }
452
453 /// Builds the variable map.
454 void traverseCFG(CFG *CFGraph, PostOrderCFGView *SortedGraph,
455 std::vector<CFGBlockInfo> &BlockInfo);
456
457protected:
458 // Get the current context index
459 unsigned getContextIndex() { return SavedContexts.size()-1; }
460
461 // Save the current context for later replay
462 void saveContext(Stmt *S, Context C) {
463 SavedContexts.push_back(std::make_pair(S,C));
464 }
465
466 // Adds a new definition to the given context, and returns a new context.
467 // This method should be called when declaring a new variable.
468 Context addDefinition(NamedDecl *D, Expr *Exp, Context Ctx) {
469 assert(!Ctx.contains(D));
470 unsigned newID = VarDefinitions.size();
471 Context NewCtx = ContextFactory.add(Ctx, D, newID);
472 VarDefinitions.push_back(VarDefinition(D, Exp, Ctx));
473 return NewCtx;
474 }
475
476 // Add a new reference to an existing definition.
477 Context addReference(NamedDecl *D, unsigned i, Context Ctx) {
478 unsigned newID = VarDefinitions.size();
479 Context NewCtx = ContextFactory.add(Ctx, D, newID);
480 VarDefinitions.push_back(VarDefinition(D, i, Ctx));
481 return NewCtx;
482 }
483
484 // Updates a definition only if that definition is already in the map.
485 // This method should be called when assigning to an existing variable.
486 Context updateDefinition(NamedDecl *D, Expr *Exp, Context Ctx) {
487 if (Ctx.contains(D)) {
488 unsigned newID = VarDefinitions.size();
489 Context NewCtx = ContextFactory.remove(Ctx, D);
490 NewCtx = ContextFactory.add(NewCtx, D, newID);
491 VarDefinitions.push_back(VarDefinition(D, Exp, Ctx));
492 return NewCtx;
493 }
494 return Ctx;
495 }
496
497 // Removes a definition from the context, but keeps the variable name
498 // as a valid variable. The index 0 is a placeholder for cleared definitions.
499 Context clearDefinition(NamedDecl *D, Context Ctx) {
500 Context NewCtx = Ctx;
501 if (NewCtx.contains(D)) {
502 NewCtx = ContextFactory.remove(NewCtx, D);
503 NewCtx = ContextFactory.add(NewCtx, D, 0);
504 }
505 return NewCtx;
506 }
507
508 // Remove a definition entirely frmo the context.
509 Context removeDefinition(NamedDecl *D, Context Ctx) {
510 Context NewCtx = Ctx;
511 if (NewCtx.contains(D)) {
512 NewCtx = ContextFactory.remove(NewCtx, D);
513 }
514 return NewCtx;
515 }
516
517 Context intersectContexts(Context C1, Context C2);
518 Context createReferenceContext(Context C);
519 void intersectBackEdge(Context C1, Context C2);
520
521 friend class VarMapBuilder;
522};
523
524
525// This has to be defined after LocalVariableMap.
526CFGBlockInfo CFGBlockInfo::getEmptyBlockInfo(Lockset::Factory &F,
527 LocalVariableMap &M) {
528 return CFGBlockInfo(F.getEmptyMap(), M.getEmptyContext());
529}
530
531
532/// Visitor which builds a LocalVariableMap
533class VarMapBuilder : public StmtVisitor<VarMapBuilder> {
534public:
535 LocalVariableMap* VMap;
536 LocalVariableMap::Context Ctx;
537
538 VarMapBuilder(LocalVariableMap *VM, LocalVariableMap::Context C)
539 : VMap(VM), Ctx(C) {}
540
541 void VisitDeclStmt(DeclStmt *S);
542 void VisitBinaryOperator(BinaryOperator *BO);
543};
544
545
546// Add new local variables to the variable map
547void VarMapBuilder::VisitDeclStmt(DeclStmt *S) {
548 bool modifiedCtx = false;
549 DeclGroupRef DGrp = S->getDeclGroup();
550 for (DeclGroupRef::iterator I = DGrp.begin(), E = DGrp.end(); I != E; ++I) {
551 if (VarDecl *VD = dyn_cast_or_null<VarDecl>(*I)) {
552 Expr *E = VD->getInit();
553
554 // Add local variables with trivial type to the variable map
555 QualType T = VD->getType();
556 if (T.isTrivialType(VD->getASTContext())) {
557 Ctx = VMap->addDefinition(VD, E, Ctx);
558 modifiedCtx = true;
559 }
560 }
561 }
562 if (modifiedCtx)
563 VMap->saveContext(S, Ctx);
564}
565
566// Update local variable definitions in variable map
567void VarMapBuilder::VisitBinaryOperator(BinaryOperator *BO) {
568 if (!BO->isAssignmentOp())
569 return;
570
571 Expr *LHSExp = BO->getLHS()->IgnoreParenCasts();
572
573 // Update the variable map and current context.
574 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(LHSExp)) {
575 ValueDecl *VDec = DRE->getDecl();
576 if (Ctx.lookup(VDec)) {
577 if (BO->getOpcode() == BO_Assign)
578 Ctx = VMap->updateDefinition(VDec, BO->getRHS(), Ctx);
579 else
580 // FIXME -- handle compound assignment operators
581 Ctx = VMap->clearDefinition(VDec, Ctx);
582 VMap->saveContext(BO, Ctx);
583 }
584 }
585}
586
587
588// Computes the intersection of two contexts. The intersection is the
589// set of variables which have the same definition in both contexts;
590// variables with different definitions are discarded.
591LocalVariableMap::Context
592LocalVariableMap::intersectContexts(Context C1, Context C2) {
593 Context Result = C1;
594 for (Context::iterator I = C1.begin(), E = C1.end(); I != E; ++I) {
595 NamedDecl *Dec = I.getKey();
596 unsigned i1 = I.getData();
597 const unsigned *i2 = C2.lookup(Dec);
598 if (!i2) // variable doesn't exist on second path
599 Result = removeDefinition(Dec, Result);
600 else if (*i2 != i1) // variable exists, but has different definition
601 Result = clearDefinition(Dec, Result);
602 }
603 return Result;
604}
605
606// For every variable in C, create a new variable that refers to the
607// definition in C. Return a new context that contains these new variables.
608// (We use this for a naive implementation of SSA on loop back-edges.)
609LocalVariableMap::Context LocalVariableMap::createReferenceContext(Context C) {
610 Context Result = getEmptyContext();
611 for (Context::iterator I = C.begin(), E = C.end(); I != E; ++I) {
612 NamedDecl *Dec = I.getKey();
613 unsigned i = I.getData();
614 Result = addReference(Dec, i, Result);
615 }
616 return Result;
617}
618
619// This routine also takes the intersection of C1 and C2, but it does so by
620// altering the VarDefinitions. C1 must be the result of an earlier call to
621// createReferenceContext.
622void LocalVariableMap::intersectBackEdge(Context C1, Context C2) {
623 for (Context::iterator I = C1.begin(), E = C1.end(); I != E; ++I) {
624 NamedDecl *Dec = I.getKey();
625 unsigned i1 = I.getData();
626 VarDefinition *VDef = &VarDefinitions[i1];
627 assert(VDef->isReference());
628
629 const unsigned *i2 = C2.lookup(Dec);
630 if (!i2 || (*i2 != i1))
631 VDef->Ref = 0; // Mark this variable as undefined
632 }
633}
634
635
636// Traverse the CFG in topological order, so all predecessors of a block
637// (excluding back-edges) are visited before the block itself. At
638// each point in the code, we calculate a Context, which holds the set of
639// variable definitions which are visible at that point in execution.
640// Visible variables are mapped to their definitions using an array that
641// contains all definitions.
642//
643// At join points in the CFG, the set is computed as the intersection of
644// the incoming sets along each edge, E.g.
645//
646// { Context | VarDefinitions }
647// int x = 0; { x -> x1 | x1 = 0 }
648// int y = 0; { x -> x1, y -> y1 | y1 = 0, x1 = 0 }
649// if (b) x = 1; { x -> x2, y -> y1 | x2 = 1, y1 = 0, ... }
650// else x = 2; { x -> x3, y -> y1 | x3 = 2, x2 = 1, ... }
651// ... { y -> y1 (x is unknown) | x3 = 2, x2 = 1, ... }
652//
653// This is essentially a simpler and more naive version of the standard SSA
654// algorithm. Those definitions that remain in the intersection are from blocks
655// that strictly dominate the current block. We do not bother to insert proper
656// phi nodes, because they are not used in our analysis; instead, wherever
657// a phi node would be required, we simply remove that definition from the
658// context (E.g. x above).
659//
660// The initial traversal does not capture back-edges, so those need to be
661// handled on a separate pass. Whenever the first pass encounters an
662// incoming back edge, it duplicates the context, creating new definitions
663// that refer back to the originals. (These correspond to places where SSA
664// might have to insert a phi node.) On the second pass, these definitions are
665// set to NULL if the the variable has changed on the back-edge (i.e. a phi
666// node was actually required.) E.g.
667//
668// { Context | VarDefinitions }
669// int x = 0, y = 0; { x -> x1, y -> y1 | y1 = 0, x1 = 0 }
670// while (b) { x -> x2, y -> y1 | [1st:] x2=x1; [2nd:] x2=NULL; }
671// x = x+1; { x -> x3, y -> y1 | x3 = x2 + 1, ... }
672// ... { y -> y1 | x3 = 2, x2 = 1, ... }
673//
674void LocalVariableMap::traverseCFG(CFG *CFGraph,
675 PostOrderCFGView *SortedGraph,
676 std::vector<CFGBlockInfo> &BlockInfo) {
677 PostOrderCFGView::CFGBlockSet VisitedBlocks(CFGraph);
678
679 CtxIndices.resize(CFGraph->getNumBlockIDs());
680
681 for (PostOrderCFGView::iterator I = SortedGraph->begin(),
682 E = SortedGraph->end(); I!= E; ++I) {
683 const CFGBlock *CurrBlock = *I;
684 int CurrBlockID = CurrBlock->getBlockID();
685 CFGBlockInfo *CurrBlockInfo = &BlockInfo[CurrBlockID];
686
687 VisitedBlocks.insert(CurrBlock);
688
689 // Calculate the entry context for the current block
690 bool HasBackEdges = false;
691 bool CtxInit = true;
692 for (CFGBlock::const_pred_iterator PI = CurrBlock->pred_begin(),
693 PE = CurrBlock->pred_end(); PI != PE; ++PI) {
694 // if *PI -> CurrBlock is a back edge, so skip it
695 if (*PI == 0 || !VisitedBlocks.alreadySet(*PI)) {
696 HasBackEdges = true;
697 continue;
698 }
699
700 int PrevBlockID = (*PI)->getBlockID();
701 CFGBlockInfo *PrevBlockInfo = &BlockInfo[PrevBlockID];
702
703 if (CtxInit) {
704 CurrBlockInfo->EntryContext = PrevBlockInfo->ExitContext;
705 CtxInit = false;
706 }
707 else {
708 CurrBlockInfo->EntryContext =
709 intersectContexts(CurrBlockInfo->EntryContext,
710 PrevBlockInfo->ExitContext);
711 }
712 }
713
714 // Duplicate the context if we have back-edges, so we can call
715 // intersectBackEdges later.
716 if (HasBackEdges)
717 CurrBlockInfo->EntryContext =
718 createReferenceContext(CurrBlockInfo->EntryContext);
719
720 // Create a starting context index for the current block
721 saveContext(0, CurrBlockInfo->EntryContext);
722 CurrBlockInfo->EntryIndex = getContextIndex();
723
724 // Visit all the statements in the basic block.
725 VarMapBuilder VMapBuilder(this, CurrBlockInfo->EntryContext);
726 for (CFGBlock::const_iterator BI = CurrBlock->begin(),
727 BE = CurrBlock->end(); BI != BE; ++BI) {
728 switch (BI->getKind()) {
729 case CFGElement::Statement: {
730 const CFGStmt *CS = cast<CFGStmt>(&*BI);
731 VMapBuilder.Visit(const_cast<Stmt*>(CS->getStmt()));
732 break;
733 }
734 default:
735 break;
736 }
737 }
738 CurrBlockInfo->ExitContext = VMapBuilder.Ctx;
739
740 // Mark variables on back edges as "unknown" if they've been changed.
741 for (CFGBlock::const_succ_iterator SI = CurrBlock->succ_begin(),
742 SE = CurrBlock->succ_end(); SI != SE; ++SI) {
743 // if CurrBlock -> *SI is *not* a back edge
744 if (*SI == 0 || !VisitedBlocks.alreadySet(*SI))
745 continue;
746
747 CFGBlock *FirstLoopBlock = *SI;
748 Context LoopBegin = BlockInfo[FirstLoopBlock->getBlockID()].EntryContext;
749 Context LoopEnd = CurrBlockInfo->ExitContext;
750 intersectBackEdge(LoopBegin, LoopEnd);
751 }
752 }
753
754 // Put an extra entry at the end of the indexed context array
755 unsigned exitID = CFGraph->getExit().getBlockID();
756 saveContext(0, BlockInfo[exitID].ExitContext);
757}
758
759
760/// \brief Class which implements the core thread safety analysis routines.
761class ThreadSafetyAnalyzer {
762 friend class BuildLockset;
763
764 ThreadSafetyHandler &Handler;
765 Lockset::Factory LocksetFactory;
766 LocalVariableMap LocalVarMap;
767
768public:
769 ThreadSafetyAnalyzer(ThreadSafetyHandler &H) : Handler(H) {}
770
771 Lockset intersectAndWarn(const Lockset LSet1, const Lockset LSet2,
772 LockErrorKind LEK);
773
774 Lockset addLock(Lockset &LSet, Expr *MutexExp, const NamedDecl *D,
775 LockKind LK, SourceLocation Loc);
776
777 void runAnalysis(AnalysisDeclContext &AC);
778};
779
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000780
781/// \brief We use this class to visit different types of expressions in
782/// CFGBlocks, and build up the lockset.
783/// An expression may cause us to add or remove locks from the lockset, or else
784/// output error messages related to missing locks.
785/// FIXME: In future, we may be able to not inherit from a visitor.
786class BuildLockset : public StmtVisitor<BuildLockset> {
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000787 friend class ThreadSafetyAnalyzer;
788
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000789 ThreadSafetyHandler &Handler;
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000790 Lockset::Factory &LocksetFactory;
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +0000791 LocalVariableMap &LocalVarMap;
792
793 Lockset LSet;
794 LocalVariableMap::Context LVarCtx;
795 unsigned CtxIndex;
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000796
797 // Helper functions
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000798 void addLock(const MutexID &Mutex, const LockData &LDat);
799 void removeLock(const MutexID &Mutex, SourceLocation UnlockLoc);
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000800
801 template <class AttrType>
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000802 void addLocksToSet(LockKind LK, AttrType *Attr,
803 Expr *Exp, NamedDecl *D, VarDecl *VD = 0);
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000804 void removeLocksFromSet(UnlockFunctionAttr *Attr,
805 Expr *Exp, NamedDecl* FunDecl);
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000806
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000807 const ValueDecl *getValueDecl(Expr *Exp);
808 void warnIfMutexNotHeld (const NamedDecl *D, Expr *Exp, AccessKind AK,
809 Expr *MutexExp, ProtectedOperationKind POK);
810 void checkAccess(Expr *Exp, AccessKind AK);
811 void checkDereference(Expr *Exp, AccessKind AK);
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000812 void handleCall(Expr *Exp, NamedDecl *D, VarDecl *VD = 0);
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000813
814 /// \brief Returns true if the lockset contains a lock, regardless of whether
815 /// the lock is held exclusively or shared.
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000816 bool locksetContains(const MutexID &Lock) const {
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000817 return LSet.lookup(Lock);
818 }
819
820 /// \brief Returns true if the lockset contains a lock with the passed in
821 /// locktype.
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000822 bool locksetContains(const MutexID &Lock, LockKind KindRequested) const {
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000823 const LockData *LockHeld = LSet.lookup(Lock);
824 return (LockHeld && KindRequested == LockHeld->LKind);
825 }
826
827 /// \brief Returns true if the lockset contains a lock with at least the
828 /// passed in locktype. So for example, if we pass in LK_Shared, this function
829 /// returns true if the lock is held LK_Shared or LK_Exclusive. If we pass in
830 /// LK_Exclusive, this function returns true if the lock is held LK_Exclusive.
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000831 bool locksetContainsAtLeast(const MutexID &Lock,
832 LockKind KindRequested) const {
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000833 switch (KindRequested) {
834 case LK_Shared:
835 return locksetContains(Lock);
836 case LK_Exclusive:
837 return locksetContains(Lock, KindRequested);
838 }
Benjamin Kramerafc5b152011-09-10 21:52:04 +0000839 llvm_unreachable("Unknown LockKind");
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000840 }
841
842public:
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +0000843 BuildLockset(ThreadSafetyAnalyzer *analyzer, CFGBlockInfo &Info)
844 : StmtVisitor<BuildLockset>(),
845 Handler(analyzer->Handler),
846 LocksetFactory(analyzer->LocksetFactory),
847 LocalVarMap(analyzer->LocalVarMap),
848 LSet(Info.EntrySet),
849 LVarCtx(Info.EntryContext),
850 CtxIndex(Info.EntryIndex)
851 {}
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000852
853 void VisitUnaryOperator(UnaryOperator *UO);
854 void VisitBinaryOperator(BinaryOperator *BO);
855 void VisitCastExpr(CastExpr *CE);
DeLesley Hutchinsdf497822011-12-29 00:56:48 +0000856 void VisitCallExpr(CallExpr *Exp);
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +0000857 void VisitCXXConstructExpr(CXXConstructExpr *Exp);
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000858 void VisitDeclStmt(DeclStmt *S);
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000859};
860
861/// \brief Add a new lock to the lockset, warning if the lock is already there.
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000862/// \param Mutex -- the Mutex expression for the lock
863/// \param LDat -- the LockData for the lock
864void BuildLockset::addLock(const MutexID &Mutex, const LockData& LDat) {
865 // FIXME: deal with acquired before/after annotations.
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000866 // FIXME: Don't always warn when we have support for reentrant locks.
867 if (locksetContains(Mutex))
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000868 Handler.handleDoubleLock(Mutex.getName(), LDat.AcquireLoc);
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000869 else
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000870 LSet = LocksetFactory.add(LSet, Mutex, LDat);
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000871}
872
873/// \brief Remove a lock from the lockset, warning if the lock is not there.
874/// \param LockExp The lock expression corresponding to the lock to be removed
875/// \param UnlockLoc The source location of the unlock (only used in error msg)
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000876void BuildLockset::removeLock(const MutexID &Mutex, SourceLocation UnlockLoc) {
877 const LockData *LDat = LSet.lookup(Mutex);
878 if (!LDat)
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000879 Handler.handleUnmatchedUnlock(Mutex.getName(), UnlockLoc);
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000880 else {
881 // For scoped-lockable vars, remove the mutex associated with this var.
882 if (LDat->UnderlyingMutex.isValid())
883 removeLock(LDat->UnderlyingMutex, UnlockLoc);
884 LSet = LocksetFactory.remove(LSet, Mutex);
885 }
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000886}
887
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000888/// \brief This function, parameterized by an attribute type, is used to add a
889/// set of locks specified as attribute arguments to the lockset.
890template <typename AttrType>
891void BuildLockset::addLocksToSet(LockKind LK, AttrType *Attr,
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000892 Expr *Exp, NamedDecl* FunDecl, VarDecl *VD) {
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000893 typedef typename AttrType::args_iterator iterator_type;
894
895 SourceLocation ExpLocation = Exp->getExprLoc();
896
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000897 // Figure out if we're calling the constructor of scoped lockable class
898 bool isScopedVar = false;
899 if (VD) {
900 if (CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FunDecl)) {
901 CXXRecordDecl* PD = CD->getParent();
902 if (PD && PD->getAttr<ScopedLockableAttr>())
903 isScopedVar = true;
904 }
905 }
906
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000907 if (Attr->args_size() == 0) {
908 // The mutex held is the "this" object.
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000909 MutexID Mutex(0, Exp, FunDecl);
910 if (!Mutex.isValid())
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000911 MutexID::warnInvalidLock(Handler, 0, Exp, FunDecl);
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000912 else
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000913 addLock(Mutex, LockData(ExpLocation, LK));
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000914 return;
915 }
916
917 for (iterator_type I=Attr->args_begin(), E=Attr->args_end(); I != E; ++I) {
918 MutexID Mutex(*I, Exp, FunDecl);
919 if (!Mutex.isValid())
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000920 MutexID::warnInvalidLock(Handler, *I, Exp, FunDecl);
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000921 else {
922 addLock(Mutex, LockData(ExpLocation, LK));
923 if (isScopedVar) {
924 // For scoped lockable vars, map this var to its underlying mutex.
925 DeclRefExpr DRE(VD, VD->getType(), VK_LValue, VD->getLocation());
926 MutexID SMutex(&DRE, 0, 0);
927 addLock(SMutex, LockData(VD->getLocation(), LK, Mutex));
928 }
929 }
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000930 }
931}
932
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000933/// \brief This function removes a set of locks specified as attribute
934/// arguments from the lockset.
935void BuildLockset::removeLocksFromSet(UnlockFunctionAttr *Attr,
936 Expr *Exp, NamedDecl* FunDecl) {
937 SourceLocation ExpLocation;
938 if (Exp) ExpLocation = Exp->getExprLoc();
939
940 if (Attr->args_size() == 0) {
941 // The mutex held is the "this" object.
942 MutexID Mu(0, Exp, FunDecl);
943 if (!Mu.isValid())
944 MutexID::warnInvalidLock(Handler, 0, Exp, FunDecl);
945 else
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000946 removeLock(Mu, ExpLocation);
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000947 return;
948 }
949
950 for (UnlockFunctionAttr::args_iterator I = Attr->args_begin(),
951 E = Attr->args_end(); I != E; ++I) {
952 MutexID Mutex(*I, Exp, FunDecl);
953 if (!Mutex.isValid())
954 MutexID::warnInvalidLock(Handler, *I, Exp, FunDecl);
955 else
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000956 removeLock(Mutex, ExpLocation);
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000957 }
958}
959
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000960/// \brief Gets the value decl pointer from DeclRefExprs or MemberExprs
961const ValueDecl *BuildLockset::getValueDecl(Expr *Exp) {
962 if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Exp))
963 return DR->getDecl();
964
965 if (const MemberExpr *ME = dyn_cast<MemberExpr>(Exp))
966 return ME->getMemberDecl();
967
968 return 0;
969}
970
971/// \brief Warn if the LSet does not contain a lock sufficient to protect access
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000972/// of at least the passed in AccessKind.
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000973void BuildLockset::warnIfMutexNotHeld(const NamedDecl *D, Expr *Exp,
974 AccessKind AK, Expr *MutexExp,
975 ProtectedOperationKind POK) {
976 LockKind LK = getLockKindFromAccessKind(AK);
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000977
978 MutexID Mutex(MutexExp, Exp, D);
Caitlin Sadowski194418f2011-09-14 20:00:24 +0000979 if (!Mutex.isValid())
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000980 MutexID::warnInvalidLock(Handler, MutexExp, Exp, D);
Caitlin Sadowski194418f2011-09-14 20:00:24 +0000981 else if (!locksetContainsAtLeast(Mutex, LK))
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000982 Handler.handleMutexNotHeld(D, POK, Mutex.getName(), LK, Exp->getExprLoc());
983}
984
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000985/// \brief This method identifies variable dereferences and checks pt_guarded_by
986/// and pt_guarded_var annotations. Note that we only check these annotations
987/// at the time a pointer is dereferenced.
988/// FIXME: We need to check for other types of pointer dereferences
989/// (e.g. [], ->) and deal with them here.
990/// \param Exp An expression that has been read or written.
991void BuildLockset::checkDereference(Expr *Exp, AccessKind AK) {
992 UnaryOperator *UO = dyn_cast<UnaryOperator>(Exp);
993 if (!UO || UO->getOpcode() != clang::UO_Deref)
994 return;
995 Exp = UO->getSubExpr()->IgnoreParenCasts();
996
997 const ValueDecl *D = getValueDecl(Exp);
998 if(!D || !D->hasAttrs())
999 return;
1000
1001 if (D->getAttr<PtGuardedVarAttr>() && LSet.isEmpty())
1002 Handler.handleNoMutexHeld(D, POK_VarDereference, AK, Exp->getExprLoc());
1003
1004 const AttrVec &ArgAttrs = D->getAttrs();
1005 for(unsigned i = 0, Size = ArgAttrs.size(); i < Size; ++i)
1006 if (PtGuardedByAttr *PGBAttr = dyn_cast<PtGuardedByAttr>(ArgAttrs[i]))
1007 warnIfMutexNotHeld(D, Exp, AK, PGBAttr->getArg(), POK_VarDereference);
1008}
1009
1010/// \brief Checks guarded_by and guarded_var attributes.
1011/// Whenever we identify an access (read or write) of a DeclRefExpr or
1012/// MemberExpr, we need to check whether there are any guarded_by or
1013/// guarded_var attributes, and make sure we hold the appropriate mutexes.
1014void BuildLockset::checkAccess(Expr *Exp, AccessKind AK) {
1015 const ValueDecl *D = getValueDecl(Exp);
1016 if(!D || !D->hasAttrs())
1017 return;
1018
1019 if (D->getAttr<GuardedVarAttr>() && LSet.isEmpty())
1020 Handler.handleNoMutexHeld(D, POK_VarAccess, AK, Exp->getExprLoc());
1021
1022 const AttrVec &ArgAttrs = D->getAttrs();
1023 for(unsigned i = 0, Size = ArgAttrs.size(); i < Size; ++i)
1024 if (GuardedByAttr *GBAttr = dyn_cast<GuardedByAttr>(ArgAttrs[i]))
1025 warnIfMutexNotHeld(D, Exp, AK, GBAttr->getArg(), POK_VarAccess);
1026}
1027
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +00001028/// \brief Process a function call, method call, constructor call,
1029/// or destructor call. This involves looking at the attributes on the
1030/// corresponding function/method/constructor/destructor, issuing warnings,
1031/// and updating the locksets accordingly.
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001032///
1033/// FIXME: For classes annotated with one of the guarded annotations, we need
1034/// to treat const method calls as reads and non-const method calls as writes,
1035/// and check that the appropriate locks are held. Non-const method calls with
1036/// the same signature as const method calls can be also treated as reads.
1037///
1038/// FIXME: We need to also visit CallExprs to catch/check global functions.
Caitlin Sadowski1748b122011-09-16 00:35:54 +00001039///
1040/// FIXME: Do not flag an error for member variables accessed in constructors/
1041/// destructors
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +00001042void BuildLockset::handleCall(Expr *Exp, NamedDecl *D, VarDecl *VD) {
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001043 AttrVec &ArgAttrs = D->getAttrs();
1044 for(unsigned i = 0; i < ArgAttrs.size(); ++i) {
1045 Attr *Attr = ArgAttrs[i];
1046 switch (Attr->getKind()) {
1047 // When we encounter an exclusive lock function, we need to add the lock
1048 // to our lockset with kind exclusive.
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001049 case attr::ExclusiveLockFunction: {
1050 ExclusiveLockFunctionAttr *A = cast<ExclusiveLockFunctionAttr>(Attr);
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +00001051 addLocksToSet(LK_Exclusive, A, Exp, D, VD);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001052 break;
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001053 }
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001054
1055 // When we encounter a shared lock function, we need to add the lock
1056 // to our lockset with kind shared.
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001057 case attr::SharedLockFunction: {
1058 SharedLockFunctionAttr *A = cast<SharedLockFunctionAttr>(Attr);
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +00001059 addLocksToSet(LK_Shared, A, Exp, D, VD);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001060 break;
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001061 }
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001062
1063 // When we encounter an unlock function, we need to remove unlocked
1064 // mutexes from the lockset, and flag a warning if they are not there.
1065 case attr::UnlockFunction: {
1066 UnlockFunctionAttr *UFAttr = cast<UnlockFunctionAttr>(Attr);
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +00001067 removeLocksFromSet(UFAttr, Exp, D);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001068 break;
1069 }
1070
1071 case attr::ExclusiveLocksRequired: {
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001072 ExclusiveLocksRequiredAttr *ELRAttr =
1073 cast<ExclusiveLocksRequiredAttr>(Attr);
1074
1075 for (ExclusiveLocksRequiredAttr::args_iterator
1076 I = ELRAttr->args_begin(), E = ELRAttr->args_end(); I != E; ++I)
1077 warnIfMutexNotHeld(D, Exp, AK_Written, *I, POK_FunctionCall);
1078 break;
1079 }
1080
1081 case attr::SharedLocksRequired: {
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001082 SharedLocksRequiredAttr *SLRAttr = cast<SharedLocksRequiredAttr>(Attr);
1083
1084 for (SharedLocksRequiredAttr::args_iterator I = SLRAttr->args_begin(),
1085 E = SLRAttr->args_end(); I != E; ++I)
1086 warnIfMutexNotHeld(D, Exp, AK_Read, *I, POK_FunctionCall);
1087 break;
1088 }
1089
1090 case attr::LocksExcluded: {
1091 LocksExcludedAttr *LEAttr = cast<LocksExcludedAttr>(Attr);
1092 for (LocksExcludedAttr::args_iterator I = LEAttr->args_begin(),
1093 E = LEAttr->args_end(); I != E; ++I) {
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001094 MutexID Mutex(*I, Exp, D);
Caitlin Sadowski194418f2011-09-14 20:00:24 +00001095 if (!Mutex.isValid())
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +00001096 MutexID::warnInvalidLock(Handler, *I, Exp, D);
Caitlin Sadowski194418f2011-09-14 20:00:24 +00001097 else if (locksetContains(Mutex))
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001098 Handler.handleFunExcludesLock(D->getName(), Mutex.getName(),
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +00001099 Exp->getExprLoc());
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001100 }
1101 break;
1102 }
1103
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001104 // Ignore other (non thread-safety) attributes
1105 default:
1106 break;
1107 }
1108 }
1109}
1110
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +00001111/// \brief For unary operations which read and write a variable, we need to
1112/// check whether we hold any required mutexes. Reads are checked in
1113/// VisitCastExpr.
1114void BuildLockset::VisitUnaryOperator(UnaryOperator *UO) {
1115 switch (UO->getOpcode()) {
1116 case clang::UO_PostDec:
1117 case clang::UO_PostInc:
1118 case clang::UO_PreDec:
1119 case clang::UO_PreInc: {
1120 Expr *SubExp = UO->getSubExpr()->IgnoreParenCasts();
1121 checkAccess(SubExp, AK_Written);
1122 checkDereference(SubExp, AK_Written);
1123 break;
1124 }
1125 default:
1126 break;
1127 }
1128}
1129
1130/// For binary operations which assign to a variable (writes), we need to check
1131/// whether we hold any required mutexes.
1132/// FIXME: Deal with non-primitive types.
1133void BuildLockset::VisitBinaryOperator(BinaryOperator *BO) {
1134 if (!BO->isAssignmentOp())
1135 return;
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001136
1137 // adjust the context
1138 LVarCtx = LocalVarMap.getNextContext(CtxIndex, BO, LVarCtx);
1139
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +00001140 Expr *LHSExp = BO->getLHS()->IgnoreParenCasts();
1141 checkAccess(LHSExp, AK_Written);
1142 checkDereference(LHSExp, AK_Written);
1143}
1144
1145/// Whenever we do an LValue to Rvalue cast, we are reading a variable and
1146/// need to ensure we hold any required mutexes.
1147/// FIXME: Deal with non-primitive types.
1148void BuildLockset::VisitCastExpr(CastExpr *CE) {
1149 if (CE->getCastKind() != CK_LValueToRValue)
1150 return;
1151 Expr *SubExp = CE->getSubExpr()->IgnoreParenCasts();
1152 checkAccess(SubExp, AK_Read);
1153 checkDereference(SubExp, AK_Read);
1154}
1155
1156
DeLesley Hutchinsdf497822011-12-29 00:56:48 +00001157void BuildLockset::VisitCallExpr(CallExpr *Exp) {
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +00001158 NamedDecl *D = dyn_cast_or_null<NamedDecl>(Exp->getCalleeDecl());
1159 if(!D || !D->hasAttrs())
1160 return;
1161 handleCall(Exp, D);
1162}
1163
1164void BuildLockset::VisitCXXConstructExpr(CXXConstructExpr *Exp) {
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +00001165 // FIXME -- only handles constructors in DeclStmt below.
1166}
1167
1168void BuildLockset::VisitDeclStmt(DeclStmt *S) {
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001169 // adjust the context
1170 LVarCtx = LocalVarMap.getNextContext(CtxIndex, S, LVarCtx);
1171
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +00001172 DeclGroupRef DGrp = S->getDeclGroup();
1173 for (DeclGroupRef::iterator I = DGrp.begin(), E = DGrp.end(); I != E; ++I) {
1174 Decl *D = *I;
1175 if (VarDecl *VD = dyn_cast_or_null<VarDecl>(D)) {
1176 Expr *E = VD->getInit();
1177 if (CXXConstructExpr *CE = dyn_cast_or_null<CXXConstructExpr>(E)) {
1178 NamedDecl *CtorD = dyn_cast_or_null<NamedDecl>(CE->getConstructor());
1179 if (!CtorD || !CtorD->hasAttrs())
1180 return;
1181 handleCall(CE, CtorD, VD);
1182 }
1183 }
1184 }
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +00001185}
1186
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001187
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +00001188/// \brief Compute the intersection of two locksets and issue warnings for any
1189/// locks in the symmetric difference.
1190///
1191/// This function is used at a merge point in the CFG when comparing the lockset
1192/// of each branch being merged. For example, given the following sequence:
1193/// A; if () then B; else C; D; we need to check that the lockset after B and C
1194/// are the same. In the event of a difference, we use the intersection of these
1195/// two locksets at the start of D.
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001196Lockset ThreadSafetyAnalyzer::intersectAndWarn(const Lockset LSet1,
1197 const Lockset LSet2,
1198 LockErrorKind LEK) {
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +00001199 Lockset Intersection = LSet1;
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001200 for (Lockset::iterator I = LSet2.begin(), E = LSet2.end(); I != E; ++I) {
1201 const MutexID &LSet2Mutex = I.getKey();
1202 const LockData &LSet2LockData = I.getData();
1203 if (const LockData *LD = LSet1.lookup(LSet2Mutex)) {
1204 if (LD->LKind != LSet2LockData.LKind) {
1205 Handler.handleExclusiveAndShared(LSet2Mutex.getName(),
1206 LSet2LockData.AcquireLoc,
1207 LD->AcquireLoc);
1208 if (LD->LKind != LK_Exclusive)
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001209 Intersection = LocksetFactory.add(Intersection, LSet2Mutex,
1210 LSet2LockData);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001211 }
1212 } else {
1213 Handler.handleMutexHeldEndOfScope(LSet2Mutex.getName(),
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +00001214 LSet2LockData.AcquireLoc, LEK);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001215 }
1216 }
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001217
1218 for (Lockset::iterator I = LSet1.begin(), E = LSet1.end(); I != E; ++I) {
1219 if (!LSet2.contains(I.getKey())) {
1220 const MutexID &Mutex = I.getKey();
1221 const LockData &MissingLock = I.getData();
1222 Handler.handleMutexHeldEndOfScope(Mutex.getName(),
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +00001223 MissingLock.AcquireLoc, LEK);
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001224 Intersection = LocksetFactory.remove(Intersection, Mutex);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001225 }
1226 }
1227 return Intersection;
1228}
1229
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001230Lockset ThreadSafetyAnalyzer::addLock(Lockset &LSet, Expr *MutexExp,
1231 const NamedDecl *D,
1232 LockKind LK, SourceLocation Loc) {
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001233 MutexID Mutex(MutexExp, 0, D);
Caitlin Sadowskicb967512011-09-15 17:43:08 +00001234 if (!Mutex.isValid()) {
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +00001235 MutexID::warnInvalidLock(Handler, MutexExp, 0, D);
Caitlin Sadowskicb967512011-09-15 17:43:08 +00001236 return LSet;
1237 }
1238 LockData NewLock(Loc, LK);
1239 return LocksetFactory.add(LSet, Mutex, NewLock);
1240}
1241
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001242/// \brief Check a function's CFG for thread-safety violations.
1243///
1244/// We traverse the blocks in the CFG, compute the set of mutexes that are held
1245/// at the end of each block, and issue warnings for thread safety violations.
1246/// Each block in the CFG is traversed exactly once.
Ted Kremenek1d26f482011-10-24 01:32:45 +00001247void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) {
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001248 CFG *CFGraph = AC.getCFG();
1249 if (!CFGraph) return;
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001250 const NamedDecl *D = dyn_cast_or_null<NamedDecl>(AC.getDecl());
1251
1252 if (!D)
1253 return; // Ignore anonymous functions for now.
1254 if (D->getAttr<NoThreadSafetyAnalysisAttr>())
1255 return;
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001256
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001257 std::vector<CFGBlockInfo> BlockInfo(CFGraph->getNumBlockIDs(),
1258 CFGBlockInfo::getEmptyBlockInfo(LocksetFactory, LocalVarMap));
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001259
1260 // We need to explore the CFG via a "topological" ordering.
1261 // That way, we will be guaranteed to have information about required
1262 // predecessor locksets when exploring a new block.
Ted Kremenek439ed162011-10-22 02:14:27 +00001263 PostOrderCFGView *SortedGraph = AC.getAnalysis<PostOrderCFGView>();
1264 PostOrderCFGView::CFGBlockSet VisitedBlocks(CFGraph);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001265
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001266 // Compute SSA names for local variables
1267 LocalVarMap.traverseCFG(CFGraph, SortedGraph, BlockInfo);
1268
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001269 // Add locks from exclusive_locks_required and shared_locks_required
1270 // to initial lockset.
Ted Kremenek439ed162011-10-22 02:14:27 +00001271 if (!SortedGraph->empty() && D->hasAttrs()) {
1272 const CFGBlock *FirstBlock = *SortedGraph->begin();
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001273 Lockset &InitialLockset = BlockInfo[FirstBlock->getBlockID()].EntrySet;
Caitlin Sadowskicb967512011-09-15 17:43:08 +00001274 const AttrVec &ArgAttrs = D->getAttrs();
1275 for(unsigned i = 0; i < ArgAttrs.size(); ++i) {
1276 Attr *Attr = ArgAttrs[i];
Caitlin Sadowski1748b122011-09-16 00:35:54 +00001277 SourceLocation AttrLoc = Attr->getLocation();
Caitlin Sadowskicb967512011-09-15 17:43:08 +00001278 if (SharedLocksRequiredAttr *SLRAttr
1279 = dyn_cast<SharedLocksRequiredAttr>(Attr)) {
1280 for (SharedLocksRequiredAttr::args_iterator
1281 SLRIter = SLRAttr->args_begin(),
1282 SLREnd = SLRAttr->args_end(); SLRIter != SLREnd; ++SLRIter)
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001283 InitialLockset = addLock(InitialLockset,
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001284 *SLRIter, D, LK_Shared,
Caitlin Sadowski1748b122011-09-16 00:35:54 +00001285 AttrLoc);
Caitlin Sadowskicb967512011-09-15 17:43:08 +00001286 } else if (ExclusiveLocksRequiredAttr *ELRAttr
1287 = dyn_cast<ExclusiveLocksRequiredAttr>(Attr)) {
1288 for (ExclusiveLocksRequiredAttr::args_iterator
1289 ELRIter = ELRAttr->args_begin(),
1290 ELREnd = ELRAttr->args_end(); ELRIter != ELREnd; ++ELRIter)
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001291 InitialLockset = addLock(InitialLockset,
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001292 *ELRIter, D, LK_Exclusive,
Caitlin Sadowski1748b122011-09-16 00:35:54 +00001293 AttrLoc);
Caitlin Sadowskicb967512011-09-15 17:43:08 +00001294 }
1295 }
1296 }
1297
Ted Kremenek439ed162011-10-22 02:14:27 +00001298 for (PostOrderCFGView::iterator I = SortedGraph->begin(),
1299 E = SortedGraph->end(); I!= E; ++I) {
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001300 const CFGBlock *CurrBlock = *I;
1301 int CurrBlockID = CurrBlock->getBlockID();
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001302 CFGBlockInfo *CurrBlockInfo = &BlockInfo[CurrBlockID];
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001303
1304 // Use the default initial lockset in case there are no predecessors.
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001305 VisitedBlocks.insert(CurrBlock);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001306
1307 // Iterate through the predecessor blocks and warn if the lockset for all
1308 // predecessors is not the same. We take the entry lockset of the current
1309 // block to be the intersection of all previous locksets.
1310 // FIXME: By keeping the intersection, we may output more errors in future
1311 // for a lock which is not in the intersection, but was in the union. We
1312 // may want to also keep the union in future. As an example, let's say
1313 // the intersection contains Mutex L, and the union contains L and M.
1314 // Later we unlock M. At this point, we would output an error because we
1315 // never locked M; although the real error is probably that we forgot to
1316 // lock M on all code paths. Conversely, let's say that later we lock M.
1317 // In this case, we should compare against the intersection instead of the
1318 // union because the real error is probably that we forgot to unlock M on
1319 // all code paths.
1320 bool LocksetInitialized = false;
1321 for (CFGBlock::const_pred_iterator PI = CurrBlock->pred_begin(),
1322 PE = CurrBlock->pred_end(); PI != PE; ++PI) {
1323
1324 // if *PI -> CurrBlock is a back edge
1325 if (*PI == 0 || !VisitedBlocks.alreadySet(*PI))
1326 continue;
1327
1328 int PrevBlockID = (*PI)->getBlockID();
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001329 CFGBlockInfo *PrevBlockInfo = &BlockInfo[PrevBlockID];
1330
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001331 if (!LocksetInitialized) {
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001332 CurrBlockInfo->EntrySet = PrevBlockInfo->ExitSet;
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001333 LocksetInitialized = true;
1334 } else {
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001335 CurrBlockInfo->EntrySet =
1336 intersectAndWarn(CurrBlockInfo->EntrySet, PrevBlockInfo->ExitSet,
1337 LEK_LockedSomePredecessors);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001338 }
1339 }
1340
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001341 BuildLockset LocksetBuilder(this, *CurrBlockInfo);
1342 // Visit all the statements in the basic block.
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001343 for (CFGBlock::const_iterator BI = CurrBlock->begin(),
1344 BE = CurrBlock->end(); BI != BE; ++BI) {
DeLesley Hutchins6db51f72011-10-21 20:51:27 +00001345 switch (BI->getKind()) {
1346 case CFGElement::Statement: {
1347 const CFGStmt *CS = cast<CFGStmt>(&*BI);
1348 LocksetBuilder.Visit(const_cast<Stmt*>(CS->getStmt()));
1349 break;
1350 }
1351 // Ignore BaseDtor, MemberDtor, and TemporaryDtor for now.
1352 case CFGElement::AutomaticObjectDtor: {
1353 const CFGAutomaticObjDtor *AD = cast<CFGAutomaticObjDtor>(&*BI);
1354 CXXDestructorDecl *DD = const_cast<CXXDestructorDecl*>(
1355 AD->getDestructorDecl(AC.getASTContext()));
1356 if (!DD->hasAttrs())
1357 break;
1358
1359 // Create a dummy expression,
1360 VarDecl *VD = const_cast<VarDecl*>(AD->getVarDecl());
1361 DeclRefExpr DRE(VD, VD->getType(), VK_LValue,
1362 AD->getTriggerStmt()->getLocEnd());
1363 LocksetBuilder.handleCall(&DRE, DD);
1364 break;
1365 }
1366 default:
1367 break;
1368 }
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001369 }
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001370 CurrBlockInfo->ExitSet = LocksetBuilder.LSet;
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001371
1372 // For every back edge from CurrBlock (the end of the loop) to another block
1373 // (FirstLoopBlock) we need to check that the Lockset of Block is equal to
1374 // the one held at the beginning of FirstLoopBlock. We can look up the
1375 // Lockset held at the beginning of FirstLoopBlock in the EntryLockSets map.
1376 for (CFGBlock::const_succ_iterator SI = CurrBlock->succ_begin(),
1377 SE = CurrBlock->succ_end(); SI != SE; ++SI) {
1378
1379 // if CurrBlock -> *SI is *not* a back edge
1380 if (*SI == 0 || !VisitedBlocks.alreadySet(*SI))
1381 continue;
1382
1383 CFGBlock *FirstLoopBlock = *SI;
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001384 Lockset PreLoop = BlockInfo[FirstLoopBlock->getBlockID()].EntrySet;
1385 Lockset LoopEnd = BlockInfo[CurrBlockID].ExitSet;
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001386 intersectAndWarn(LoopEnd, PreLoop, LEK_LockedSomeLoopIterations);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001387 }
1388 }
1389
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001390 Lockset InitialLockset = BlockInfo[CFGraph->getEntry().getBlockID()].EntrySet;
1391 Lockset FinalLockset = BlockInfo[CFGraph->getExit().getBlockID()].ExitSet;
Caitlin Sadowski1748b122011-09-16 00:35:54 +00001392
1393 // FIXME: Should we call this function for all blocks which exit the function?
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001394 intersectAndWarn(InitialLockset, FinalLockset, LEK_LockedAtEndOfFunction);
1395}
1396
1397} // end anonymous namespace
1398
1399
1400namespace clang {
1401namespace thread_safety {
1402
1403/// \brief Check a function's CFG for thread-safety violations.
1404///
1405/// We traverse the blocks in the CFG, compute the set of mutexes that are held
1406/// at the end of each block, and issue warnings for thread safety violations.
1407/// Each block in the CFG is traversed exactly once.
Ted Kremenek1d26f482011-10-24 01:32:45 +00001408void runThreadSafetyAnalysis(AnalysisDeclContext &AC,
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001409 ThreadSafetyHandler &Handler) {
1410 ThreadSafetyAnalyzer Analyzer(Handler);
1411 Analyzer.runAnalysis(AC);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001412}
1413
1414/// \brief Helper function that returns a LockKind required for the given level
1415/// of access.
1416LockKind getLockKindFromAccessKind(AccessKind AK) {
1417 switch (AK) {
1418 case AK_Read :
1419 return LK_Shared;
1420 case AK_Written :
1421 return LK_Exclusive;
1422 }
Benjamin Kramerafc5b152011-09-10 21:52:04 +00001423 llvm_unreachable("Unknown AccessKind");
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001424}
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001425
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001426}} // end namespace clang::thread_safety