blob: 25f86084cf00241023c596fcf1aa8fffb0464727 [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
DeLesley Hutchinsb4fa4182012-01-06 19:16:50 +0000382 /// NULL if the expression is not statically known. If successful, also
383 /// modifies Ctx to hold the context of the return Expr.
384 Expr* lookupExpr(NamedDecl *D, Context &Ctx) {
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +0000385 const unsigned *P = Ctx.lookup(D);
386 if (!P)
387 return 0;
388
389 unsigned i = *P;
390 while (i > 0) {
DeLesley Hutchinsb4fa4182012-01-06 19:16:50 +0000391 if (VarDefinitions[i].Exp) {
392 Ctx = VarDefinitions[i].Ctx;
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +0000393 return VarDefinitions[i].Exp;
DeLesley Hutchinsb4fa4182012-01-06 19:16:50 +0000394 }
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +0000395 i = VarDefinitions[i].Ref;
396 }
397 return 0;
398 }
399
400 Context getEmptyContext() { return ContextFactory.getEmptyMap(); }
401
402 /// Return the next context after processing S. This function is used by
403 /// clients of the class to get the appropriate context when traversing the
404 /// CFG. It must be called for every assignment or DeclStmt.
405 Context getNextContext(unsigned &CtxIndex, Stmt *S, Context C) {
406 if (SavedContexts[CtxIndex+1].first == S) {
407 CtxIndex++;
408 Context Result = SavedContexts[CtxIndex].second;
409 return Result;
410 }
411 return C;
412 }
413
414 void dumpVarDefinitionName(unsigned i) {
415 if (i == 0) {
416 llvm::errs() << "Undefined";
417 return;
418 }
419 NamedDecl *Dec = VarDefinitions[i].Dec;
420 if (!Dec) {
421 llvm::errs() << "<<NULL>>";
422 return;
423 }
424 Dec->printName(llvm::errs());
425 llvm::errs() << "." << i << " " << ((void*) Dec);
426 }
427
428 /// Dumps an ASCII representation of the variable map to llvm::errs()
429 void dump() {
430 for (unsigned i = 1, e = VarDefinitions.size(); i < e; ++i) {
431 Expr *Exp = VarDefinitions[i].Exp;
432 unsigned Ref = VarDefinitions[i].Ref;
433
434 dumpVarDefinitionName(i);
435 llvm::errs() << " = ";
436 if (Exp) Exp->dump();
437 else {
438 dumpVarDefinitionName(Ref);
439 llvm::errs() << "\n";
440 }
441 }
442 }
443
444 /// Dumps an ASCII representation of a Context to llvm::errs()
445 void dumpContext(Context C) {
446 for (Context::iterator I = C.begin(), E = C.end(); I != E; ++I) {
447 NamedDecl *D = I.getKey();
448 D->printName(llvm::errs());
449 const unsigned *i = C.lookup(D);
450 llvm::errs() << " -> ";
451 dumpVarDefinitionName(*i);
452 llvm::errs() << "\n";
453 }
454 }
455
456 /// Builds the variable map.
457 void traverseCFG(CFG *CFGraph, PostOrderCFGView *SortedGraph,
458 std::vector<CFGBlockInfo> &BlockInfo);
459
460protected:
461 // Get the current context index
462 unsigned getContextIndex() { return SavedContexts.size()-1; }
463
464 // Save the current context for later replay
465 void saveContext(Stmt *S, Context C) {
466 SavedContexts.push_back(std::make_pair(S,C));
467 }
468
469 // Adds a new definition to the given context, and returns a new context.
470 // This method should be called when declaring a new variable.
471 Context addDefinition(NamedDecl *D, Expr *Exp, Context Ctx) {
472 assert(!Ctx.contains(D));
473 unsigned newID = VarDefinitions.size();
474 Context NewCtx = ContextFactory.add(Ctx, D, newID);
475 VarDefinitions.push_back(VarDefinition(D, Exp, Ctx));
476 return NewCtx;
477 }
478
479 // Add a new reference to an existing definition.
480 Context addReference(NamedDecl *D, unsigned i, Context Ctx) {
481 unsigned newID = VarDefinitions.size();
482 Context NewCtx = ContextFactory.add(Ctx, D, newID);
483 VarDefinitions.push_back(VarDefinition(D, i, Ctx));
484 return NewCtx;
485 }
486
487 // Updates a definition only if that definition is already in the map.
488 // This method should be called when assigning to an existing variable.
489 Context updateDefinition(NamedDecl *D, Expr *Exp, Context Ctx) {
490 if (Ctx.contains(D)) {
491 unsigned newID = VarDefinitions.size();
492 Context NewCtx = ContextFactory.remove(Ctx, D);
493 NewCtx = ContextFactory.add(NewCtx, D, newID);
494 VarDefinitions.push_back(VarDefinition(D, Exp, Ctx));
495 return NewCtx;
496 }
497 return Ctx;
498 }
499
500 // Removes a definition from the context, but keeps the variable name
501 // as a valid variable. The index 0 is a placeholder for cleared definitions.
502 Context clearDefinition(NamedDecl *D, Context Ctx) {
503 Context NewCtx = Ctx;
504 if (NewCtx.contains(D)) {
505 NewCtx = ContextFactory.remove(NewCtx, D);
506 NewCtx = ContextFactory.add(NewCtx, D, 0);
507 }
508 return NewCtx;
509 }
510
511 // Remove a definition entirely frmo the context.
512 Context removeDefinition(NamedDecl *D, Context Ctx) {
513 Context NewCtx = Ctx;
514 if (NewCtx.contains(D)) {
515 NewCtx = ContextFactory.remove(NewCtx, D);
516 }
517 return NewCtx;
518 }
519
520 Context intersectContexts(Context C1, Context C2);
521 Context createReferenceContext(Context C);
522 void intersectBackEdge(Context C1, Context C2);
523
524 friend class VarMapBuilder;
525};
526
527
528// This has to be defined after LocalVariableMap.
529CFGBlockInfo CFGBlockInfo::getEmptyBlockInfo(Lockset::Factory &F,
530 LocalVariableMap &M) {
531 return CFGBlockInfo(F.getEmptyMap(), M.getEmptyContext());
532}
533
534
535/// Visitor which builds a LocalVariableMap
536class VarMapBuilder : public StmtVisitor<VarMapBuilder> {
537public:
538 LocalVariableMap* VMap;
539 LocalVariableMap::Context Ctx;
540
541 VarMapBuilder(LocalVariableMap *VM, LocalVariableMap::Context C)
542 : VMap(VM), Ctx(C) {}
543
544 void VisitDeclStmt(DeclStmt *S);
545 void VisitBinaryOperator(BinaryOperator *BO);
546};
547
548
549// Add new local variables to the variable map
550void VarMapBuilder::VisitDeclStmt(DeclStmt *S) {
551 bool modifiedCtx = false;
552 DeclGroupRef DGrp = S->getDeclGroup();
553 for (DeclGroupRef::iterator I = DGrp.begin(), E = DGrp.end(); I != E; ++I) {
554 if (VarDecl *VD = dyn_cast_or_null<VarDecl>(*I)) {
555 Expr *E = VD->getInit();
556
557 // Add local variables with trivial type to the variable map
558 QualType T = VD->getType();
559 if (T.isTrivialType(VD->getASTContext())) {
560 Ctx = VMap->addDefinition(VD, E, Ctx);
561 modifiedCtx = true;
562 }
563 }
564 }
565 if (modifiedCtx)
566 VMap->saveContext(S, Ctx);
567}
568
569// Update local variable definitions in variable map
570void VarMapBuilder::VisitBinaryOperator(BinaryOperator *BO) {
571 if (!BO->isAssignmentOp())
572 return;
573
574 Expr *LHSExp = BO->getLHS()->IgnoreParenCasts();
575
576 // Update the variable map and current context.
577 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(LHSExp)) {
578 ValueDecl *VDec = DRE->getDecl();
579 if (Ctx.lookup(VDec)) {
580 if (BO->getOpcode() == BO_Assign)
581 Ctx = VMap->updateDefinition(VDec, BO->getRHS(), Ctx);
582 else
583 // FIXME -- handle compound assignment operators
584 Ctx = VMap->clearDefinition(VDec, Ctx);
585 VMap->saveContext(BO, Ctx);
586 }
587 }
588}
589
590
591// Computes the intersection of two contexts. The intersection is the
592// set of variables which have the same definition in both contexts;
593// variables with different definitions are discarded.
594LocalVariableMap::Context
595LocalVariableMap::intersectContexts(Context C1, Context C2) {
596 Context Result = C1;
597 for (Context::iterator I = C1.begin(), E = C1.end(); I != E; ++I) {
598 NamedDecl *Dec = I.getKey();
599 unsigned i1 = I.getData();
600 const unsigned *i2 = C2.lookup(Dec);
601 if (!i2) // variable doesn't exist on second path
602 Result = removeDefinition(Dec, Result);
603 else if (*i2 != i1) // variable exists, but has different definition
604 Result = clearDefinition(Dec, Result);
605 }
606 return Result;
607}
608
609// For every variable in C, create a new variable that refers to the
610// definition in C. Return a new context that contains these new variables.
611// (We use this for a naive implementation of SSA on loop back-edges.)
612LocalVariableMap::Context LocalVariableMap::createReferenceContext(Context C) {
613 Context Result = getEmptyContext();
614 for (Context::iterator I = C.begin(), E = C.end(); I != E; ++I) {
615 NamedDecl *Dec = I.getKey();
616 unsigned i = I.getData();
617 Result = addReference(Dec, i, Result);
618 }
619 return Result;
620}
621
622// This routine also takes the intersection of C1 and C2, but it does so by
623// altering the VarDefinitions. C1 must be the result of an earlier call to
624// createReferenceContext.
625void LocalVariableMap::intersectBackEdge(Context C1, Context C2) {
626 for (Context::iterator I = C1.begin(), E = C1.end(); I != E; ++I) {
627 NamedDecl *Dec = I.getKey();
628 unsigned i1 = I.getData();
629 VarDefinition *VDef = &VarDefinitions[i1];
630 assert(VDef->isReference());
631
632 const unsigned *i2 = C2.lookup(Dec);
633 if (!i2 || (*i2 != i1))
634 VDef->Ref = 0; // Mark this variable as undefined
635 }
636}
637
638
639// Traverse the CFG in topological order, so all predecessors of a block
640// (excluding back-edges) are visited before the block itself. At
641// each point in the code, we calculate a Context, which holds the set of
642// variable definitions which are visible at that point in execution.
643// Visible variables are mapped to their definitions using an array that
644// contains all definitions.
645//
646// At join points in the CFG, the set is computed as the intersection of
647// the incoming sets along each edge, E.g.
648//
649// { Context | VarDefinitions }
650// int x = 0; { x -> x1 | x1 = 0 }
651// int y = 0; { x -> x1, y -> y1 | y1 = 0, x1 = 0 }
652// if (b) x = 1; { x -> x2, y -> y1 | x2 = 1, y1 = 0, ... }
653// else x = 2; { x -> x3, y -> y1 | x3 = 2, x2 = 1, ... }
654// ... { y -> y1 (x is unknown) | x3 = 2, x2 = 1, ... }
655//
656// This is essentially a simpler and more naive version of the standard SSA
657// algorithm. Those definitions that remain in the intersection are from blocks
658// that strictly dominate the current block. We do not bother to insert proper
659// phi nodes, because they are not used in our analysis; instead, wherever
660// a phi node would be required, we simply remove that definition from the
661// context (E.g. x above).
662//
663// The initial traversal does not capture back-edges, so those need to be
664// handled on a separate pass. Whenever the first pass encounters an
665// incoming back edge, it duplicates the context, creating new definitions
666// that refer back to the originals. (These correspond to places where SSA
667// might have to insert a phi node.) On the second pass, these definitions are
668// set to NULL if the the variable has changed on the back-edge (i.e. a phi
669// node was actually required.) E.g.
670//
671// { Context | VarDefinitions }
672// int x = 0, y = 0; { x -> x1, y -> y1 | y1 = 0, x1 = 0 }
673// while (b) { x -> x2, y -> y1 | [1st:] x2=x1; [2nd:] x2=NULL; }
674// x = x+1; { x -> x3, y -> y1 | x3 = x2 + 1, ... }
675// ... { y -> y1 | x3 = 2, x2 = 1, ... }
676//
677void LocalVariableMap::traverseCFG(CFG *CFGraph,
678 PostOrderCFGView *SortedGraph,
679 std::vector<CFGBlockInfo> &BlockInfo) {
680 PostOrderCFGView::CFGBlockSet VisitedBlocks(CFGraph);
681
682 CtxIndices.resize(CFGraph->getNumBlockIDs());
683
684 for (PostOrderCFGView::iterator I = SortedGraph->begin(),
685 E = SortedGraph->end(); I!= E; ++I) {
686 const CFGBlock *CurrBlock = *I;
687 int CurrBlockID = CurrBlock->getBlockID();
688 CFGBlockInfo *CurrBlockInfo = &BlockInfo[CurrBlockID];
689
690 VisitedBlocks.insert(CurrBlock);
691
692 // Calculate the entry context for the current block
693 bool HasBackEdges = false;
694 bool CtxInit = true;
695 for (CFGBlock::const_pred_iterator PI = CurrBlock->pred_begin(),
696 PE = CurrBlock->pred_end(); PI != PE; ++PI) {
697 // if *PI -> CurrBlock is a back edge, so skip it
698 if (*PI == 0 || !VisitedBlocks.alreadySet(*PI)) {
699 HasBackEdges = true;
700 continue;
701 }
702
703 int PrevBlockID = (*PI)->getBlockID();
704 CFGBlockInfo *PrevBlockInfo = &BlockInfo[PrevBlockID];
705
706 if (CtxInit) {
707 CurrBlockInfo->EntryContext = PrevBlockInfo->ExitContext;
708 CtxInit = false;
709 }
710 else {
711 CurrBlockInfo->EntryContext =
712 intersectContexts(CurrBlockInfo->EntryContext,
713 PrevBlockInfo->ExitContext);
714 }
715 }
716
717 // Duplicate the context if we have back-edges, so we can call
718 // intersectBackEdges later.
719 if (HasBackEdges)
720 CurrBlockInfo->EntryContext =
721 createReferenceContext(CurrBlockInfo->EntryContext);
722
723 // Create a starting context index for the current block
724 saveContext(0, CurrBlockInfo->EntryContext);
725 CurrBlockInfo->EntryIndex = getContextIndex();
726
727 // Visit all the statements in the basic block.
728 VarMapBuilder VMapBuilder(this, CurrBlockInfo->EntryContext);
729 for (CFGBlock::const_iterator BI = CurrBlock->begin(),
730 BE = CurrBlock->end(); BI != BE; ++BI) {
731 switch (BI->getKind()) {
732 case CFGElement::Statement: {
733 const CFGStmt *CS = cast<CFGStmt>(&*BI);
734 VMapBuilder.Visit(const_cast<Stmt*>(CS->getStmt()));
735 break;
736 }
737 default:
738 break;
739 }
740 }
741 CurrBlockInfo->ExitContext = VMapBuilder.Ctx;
742
743 // Mark variables on back edges as "unknown" if they've been changed.
744 for (CFGBlock::const_succ_iterator SI = CurrBlock->succ_begin(),
745 SE = CurrBlock->succ_end(); SI != SE; ++SI) {
746 // if CurrBlock -> *SI is *not* a back edge
747 if (*SI == 0 || !VisitedBlocks.alreadySet(*SI))
748 continue;
749
750 CFGBlock *FirstLoopBlock = *SI;
751 Context LoopBegin = BlockInfo[FirstLoopBlock->getBlockID()].EntryContext;
752 Context LoopEnd = CurrBlockInfo->ExitContext;
753 intersectBackEdge(LoopBegin, LoopEnd);
754 }
755 }
756
757 // Put an extra entry at the end of the indexed context array
758 unsigned exitID = CFGraph->getExit().getBlockID();
759 saveContext(0, BlockInfo[exitID].ExitContext);
760}
761
762
763/// \brief Class which implements the core thread safety analysis routines.
764class ThreadSafetyAnalyzer {
765 friend class BuildLockset;
766
767 ThreadSafetyHandler &Handler;
768 Lockset::Factory LocksetFactory;
769 LocalVariableMap LocalVarMap;
770
771public:
772 ThreadSafetyAnalyzer(ThreadSafetyHandler &H) : Handler(H) {}
773
774 Lockset intersectAndWarn(const Lockset LSet1, const Lockset LSet2,
775 LockErrorKind LEK);
776
777 Lockset addLock(Lockset &LSet, Expr *MutexExp, const NamedDecl *D,
778 LockKind LK, SourceLocation Loc);
779
780 void runAnalysis(AnalysisDeclContext &AC);
781};
782
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000783
784/// \brief We use this class to visit different types of expressions in
785/// CFGBlocks, and build up the lockset.
786/// An expression may cause us to add or remove locks from the lockset, or else
787/// output error messages related to missing locks.
788/// FIXME: In future, we may be able to not inherit from a visitor.
789class BuildLockset : public StmtVisitor<BuildLockset> {
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000790 friend class ThreadSafetyAnalyzer;
791
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000792 ThreadSafetyHandler &Handler;
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000793 Lockset::Factory &LocksetFactory;
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +0000794 LocalVariableMap &LocalVarMap;
795
796 Lockset LSet;
797 LocalVariableMap::Context LVarCtx;
798 unsigned CtxIndex;
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000799
800 // Helper functions
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000801 void addLock(const MutexID &Mutex, const LockData &LDat);
802 void removeLock(const MutexID &Mutex, SourceLocation UnlockLoc);
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000803
804 template <class AttrType>
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000805 void addLocksToSet(LockKind LK, AttrType *Attr,
806 Expr *Exp, NamedDecl *D, VarDecl *VD = 0);
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000807 void removeLocksFromSet(UnlockFunctionAttr *Attr,
808 Expr *Exp, NamedDecl* FunDecl);
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000809
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000810 const ValueDecl *getValueDecl(Expr *Exp);
811 void warnIfMutexNotHeld (const NamedDecl *D, Expr *Exp, AccessKind AK,
812 Expr *MutexExp, ProtectedOperationKind POK);
813 void checkAccess(Expr *Exp, AccessKind AK);
814 void checkDereference(Expr *Exp, AccessKind AK);
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000815 void handleCall(Expr *Exp, NamedDecl *D, VarDecl *VD = 0);
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000816
DeLesley Hutchinsb4fa4182012-01-06 19:16:50 +0000817 template <class AttrType>
818 void addTrylock(LockKind LK, AttrType *Attr, Expr *Exp, NamedDecl *FunDecl,
819 const CFGBlock* PredBlock, const CFGBlock *CurrBlock,
820 Expr *BrE, bool Neg);
821 CallExpr* getTrylockCallExpr(Stmt *Cond, LocalVariableMap::Context C,
822 bool &Negate);
823 void handleTrylock(Stmt *Cond, const CFGBlock* PredBlock,
824 const CFGBlock *CurrBlock);
825
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000826 /// \brief Returns true if the lockset contains a lock, regardless of whether
827 /// the lock is held exclusively or shared.
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000828 bool locksetContains(const MutexID &Lock) const {
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000829 return LSet.lookup(Lock);
830 }
831
832 /// \brief Returns true if the lockset contains a lock with the passed in
833 /// locktype.
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000834 bool locksetContains(const MutexID &Lock, LockKind KindRequested) const {
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000835 const LockData *LockHeld = LSet.lookup(Lock);
836 return (LockHeld && KindRequested == LockHeld->LKind);
837 }
838
839 /// \brief Returns true if the lockset contains a lock with at least the
840 /// passed in locktype. So for example, if we pass in LK_Shared, this function
841 /// returns true if the lock is held LK_Shared or LK_Exclusive. If we pass in
842 /// LK_Exclusive, this function returns true if the lock is held LK_Exclusive.
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000843 bool locksetContainsAtLeast(const MutexID &Lock,
844 LockKind KindRequested) const {
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000845 switch (KindRequested) {
846 case LK_Shared:
847 return locksetContains(Lock);
848 case LK_Exclusive:
849 return locksetContains(Lock, KindRequested);
850 }
Benjamin Kramerafc5b152011-09-10 21:52:04 +0000851 llvm_unreachable("Unknown LockKind");
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000852 }
853
854public:
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +0000855 BuildLockset(ThreadSafetyAnalyzer *analyzer, CFGBlockInfo &Info)
856 : StmtVisitor<BuildLockset>(),
857 Handler(analyzer->Handler),
858 LocksetFactory(analyzer->LocksetFactory),
859 LocalVarMap(analyzer->LocalVarMap),
860 LSet(Info.EntrySet),
861 LVarCtx(Info.EntryContext),
862 CtxIndex(Info.EntryIndex)
863 {}
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000864
865 void VisitUnaryOperator(UnaryOperator *UO);
866 void VisitBinaryOperator(BinaryOperator *BO);
867 void VisitCastExpr(CastExpr *CE);
DeLesley Hutchinsdf497822011-12-29 00:56:48 +0000868 void VisitCallExpr(CallExpr *Exp);
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +0000869 void VisitCXXConstructExpr(CXXConstructExpr *Exp);
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000870 void VisitDeclStmt(DeclStmt *S);
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000871};
872
873/// \brief Add a new lock to the lockset, warning if the lock is already there.
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000874/// \param Mutex -- the Mutex expression for the lock
875/// \param LDat -- the LockData for the lock
876void BuildLockset::addLock(const MutexID &Mutex, const LockData& LDat) {
877 // FIXME: deal with acquired before/after annotations.
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000878 // FIXME: Don't always warn when we have support for reentrant locks.
879 if (locksetContains(Mutex))
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000880 Handler.handleDoubleLock(Mutex.getName(), LDat.AcquireLoc);
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000881 else
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000882 LSet = LocksetFactory.add(LSet, Mutex, LDat);
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000883}
884
885/// \brief Remove a lock from the lockset, warning if the lock is not there.
886/// \param LockExp The lock expression corresponding to the lock to be removed
887/// \param UnlockLoc The source location of the unlock (only used in error msg)
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000888void BuildLockset::removeLock(const MutexID &Mutex, SourceLocation UnlockLoc) {
889 const LockData *LDat = LSet.lookup(Mutex);
890 if (!LDat)
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000891 Handler.handleUnmatchedUnlock(Mutex.getName(), UnlockLoc);
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000892 else {
893 // For scoped-lockable vars, remove the mutex associated with this var.
894 if (LDat->UnderlyingMutex.isValid())
895 removeLock(LDat->UnderlyingMutex, UnlockLoc);
896 LSet = LocksetFactory.remove(LSet, Mutex);
897 }
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000898}
899
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000900/// \brief This function, parameterized by an attribute type, is used to add a
901/// set of locks specified as attribute arguments to the lockset.
902template <typename AttrType>
903void BuildLockset::addLocksToSet(LockKind LK, AttrType *Attr,
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000904 Expr *Exp, NamedDecl* FunDecl, VarDecl *VD) {
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000905 typedef typename AttrType::args_iterator iterator_type;
906
907 SourceLocation ExpLocation = Exp->getExprLoc();
908
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000909 // Figure out if we're calling the constructor of scoped lockable class
910 bool isScopedVar = false;
911 if (VD) {
912 if (CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FunDecl)) {
913 CXXRecordDecl* PD = CD->getParent();
914 if (PD && PD->getAttr<ScopedLockableAttr>())
915 isScopedVar = true;
916 }
917 }
918
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000919 if (Attr->args_size() == 0) {
920 // The mutex held is the "this" object.
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000921 MutexID Mutex(0, Exp, FunDecl);
922 if (!Mutex.isValid())
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000923 MutexID::warnInvalidLock(Handler, 0, Exp, FunDecl);
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000924 else
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000925 addLock(Mutex, LockData(ExpLocation, LK));
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000926 return;
927 }
928
929 for (iterator_type I=Attr->args_begin(), E=Attr->args_end(); I != E; ++I) {
930 MutexID Mutex(*I, Exp, FunDecl);
931 if (!Mutex.isValid())
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000932 MutexID::warnInvalidLock(Handler, *I, Exp, FunDecl);
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000933 else {
934 addLock(Mutex, LockData(ExpLocation, LK));
935 if (isScopedVar) {
936 // For scoped lockable vars, map this var to its underlying mutex.
937 DeclRefExpr DRE(VD, VD->getType(), VK_LValue, VD->getLocation());
938 MutexID SMutex(&DRE, 0, 0);
939 addLock(SMutex, LockData(VD->getLocation(), LK, Mutex));
940 }
941 }
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +0000942 }
943}
944
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000945/// \brief This function removes a set of locks specified as attribute
946/// arguments from the lockset.
947void BuildLockset::removeLocksFromSet(UnlockFunctionAttr *Attr,
948 Expr *Exp, NamedDecl* FunDecl) {
949 SourceLocation ExpLocation;
950 if (Exp) ExpLocation = Exp->getExprLoc();
951
952 if (Attr->args_size() == 0) {
953 // The mutex held is the "this" object.
954 MutexID Mu(0, Exp, FunDecl);
955 if (!Mu.isValid())
956 MutexID::warnInvalidLock(Handler, 0, Exp, FunDecl);
957 else
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000958 removeLock(Mu, ExpLocation);
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000959 return;
960 }
961
962 for (UnlockFunctionAttr::args_iterator I = Attr->args_begin(),
963 E = Attr->args_end(); I != E; ++I) {
964 MutexID Mutex(*I, Exp, FunDecl);
965 if (!Mutex.isValid())
966 MutexID::warnInvalidLock(Handler, *I, Exp, FunDecl);
967 else
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +0000968 removeLock(Mutex, ExpLocation);
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000969 }
970}
971
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000972/// \brief Gets the value decl pointer from DeclRefExprs or MemberExprs
973const ValueDecl *BuildLockset::getValueDecl(Expr *Exp) {
974 if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Exp))
975 return DR->getDecl();
976
977 if (const MemberExpr *ME = dyn_cast<MemberExpr>(Exp))
978 return ME->getMemberDecl();
979
980 return 0;
981}
982
983/// \brief Warn if the LSet does not contain a lock sufficient to protect access
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000984/// of at least the passed in AccessKind.
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000985void BuildLockset::warnIfMutexNotHeld(const NamedDecl *D, Expr *Exp,
986 AccessKind AK, Expr *MutexExp,
987 ProtectedOperationKind POK) {
988 LockKind LK = getLockKindFromAccessKind(AK);
DeLesley Hutchins9f80a972011-10-17 21:33:35 +0000989
990 MutexID Mutex(MutexExp, Exp, D);
Caitlin Sadowski194418f2011-09-14 20:00:24 +0000991 if (!Mutex.isValid())
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +0000992 MutexID::warnInvalidLock(Handler, MutexExp, Exp, D);
Caitlin Sadowski194418f2011-09-14 20:00:24 +0000993 else if (!locksetContainsAtLeast(Mutex, LK))
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000994 Handler.handleMutexNotHeld(D, POK, Mutex.getName(), LK, Exp->getExprLoc());
995}
996
Caitlin Sadowski402aa062011-09-09 16:11:56 +0000997/// \brief This method identifies variable dereferences and checks pt_guarded_by
998/// and pt_guarded_var annotations. Note that we only check these annotations
999/// at the time a pointer is dereferenced.
1000/// FIXME: We need to check for other types of pointer dereferences
1001/// (e.g. [], ->) and deal with them here.
1002/// \param Exp An expression that has been read or written.
1003void BuildLockset::checkDereference(Expr *Exp, AccessKind AK) {
1004 UnaryOperator *UO = dyn_cast<UnaryOperator>(Exp);
1005 if (!UO || UO->getOpcode() != clang::UO_Deref)
1006 return;
1007 Exp = UO->getSubExpr()->IgnoreParenCasts();
1008
1009 const ValueDecl *D = getValueDecl(Exp);
1010 if(!D || !D->hasAttrs())
1011 return;
1012
1013 if (D->getAttr<PtGuardedVarAttr>() && LSet.isEmpty())
1014 Handler.handleNoMutexHeld(D, POK_VarDereference, AK, Exp->getExprLoc());
1015
1016 const AttrVec &ArgAttrs = D->getAttrs();
1017 for(unsigned i = 0, Size = ArgAttrs.size(); i < Size; ++i)
1018 if (PtGuardedByAttr *PGBAttr = dyn_cast<PtGuardedByAttr>(ArgAttrs[i]))
1019 warnIfMutexNotHeld(D, Exp, AK, PGBAttr->getArg(), POK_VarDereference);
1020}
1021
1022/// \brief Checks guarded_by and guarded_var attributes.
1023/// Whenever we identify an access (read or write) of a DeclRefExpr or
1024/// MemberExpr, we need to check whether there are any guarded_by or
1025/// guarded_var attributes, and make sure we hold the appropriate mutexes.
1026void BuildLockset::checkAccess(Expr *Exp, AccessKind AK) {
1027 const ValueDecl *D = getValueDecl(Exp);
1028 if(!D || !D->hasAttrs())
1029 return;
1030
1031 if (D->getAttr<GuardedVarAttr>() && LSet.isEmpty())
1032 Handler.handleNoMutexHeld(D, POK_VarAccess, AK, Exp->getExprLoc());
1033
1034 const AttrVec &ArgAttrs = D->getAttrs();
1035 for(unsigned i = 0, Size = ArgAttrs.size(); i < Size; ++i)
1036 if (GuardedByAttr *GBAttr = dyn_cast<GuardedByAttr>(ArgAttrs[i]))
1037 warnIfMutexNotHeld(D, Exp, AK, GBAttr->getArg(), POK_VarAccess);
1038}
1039
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +00001040/// \brief Process a function call, method call, constructor call,
1041/// or destructor call. This involves looking at the attributes on the
1042/// corresponding function/method/constructor/destructor, issuing warnings,
1043/// and updating the locksets accordingly.
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001044///
1045/// FIXME: For classes annotated with one of the guarded annotations, we need
1046/// to treat const method calls as reads and non-const method calls as writes,
1047/// and check that the appropriate locks are held. Non-const method calls with
1048/// the same signature as const method calls can be also treated as reads.
1049///
1050/// FIXME: We need to also visit CallExprs to catch/check global functions.
Caitlin Sadowski1748b122011-09-16 00:35:54 +00001051///
1052/// FIXME: Do not flag an error for member variables accessed in constructors/
1053/// destructors
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +00001054void BuildLockset::handleCall(Expr *Exp, NamedDecl *D, VarDecl *VD) {
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001055 AttrVec &ArgAttrs = D->getAttrs();
1056 for(unsigned i = 0; i < ArgAttrs.size(); ++i) {
1057 Attr *Attr = ArgAttrs[i];
1058 switch (Attr->getKind()) {
1059 // When we encounter an exclusive lock function, we need to add the lock
1060 // to our lockset with kind exclusive.
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001061 case attr::ExclusiveLockFunction: {
1062 ExclusiveLockFunctionAttr *A = cast<ExclusiveLockFunctionAttr>(Attr);
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +00001063 addLocksToSet(LK_Exclusive, A, Exp, D, VD);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001064 break;
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001065 }
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001066
1067 // When we encounter a shared lock function, we need to add the lock
1068 // to our lockset with kind shared.
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001069 case attr::SharedLockFunction: {
1070 SharedLockFunctionAttr *A = cast<SharedLockFunctionAttr>(Attr);
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +00001071 addLocksToSet(LK_Shared, A, Exp, D, VD);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001072 break;
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001073 }
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001074
1075 // When we encounter an unlock function, we need to remove unlocked
1076 // mutexes from the lockset, and flag a warning if they are not there.
1077 case attr::UnlockFunction: {
1078 UnlockFunctionAttr *UFAttr = cast<UnlockFunctionAttr>(Attr);
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +00001079 removeLocksFromSet(UFAttr, Exp, D);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001080 break;
1081 }
1082
1083 case attr::ExclusiveLocksRequired: {
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001084 ExclusiveLocksRequiredAttr *ELRAttr =
1085 cast<ExclusiveLocksRequiredAttr>(Attr);
1086
1087 for (ExclusiveLocksRequiredAttr::args_iterator
1088 I = ELRAttr->args_begin(), E = ELRAttr->args_end(); I != E; ++I)
1089 warnIfMutexNotHeld(D, Exp, AK_Written, *I, POK_FunctionCall);
1090 break;
1091 }
1092
1093 case attr::SharedLocksRequired: {
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001094 SharedLocksRequiredAttr *SLRAttr = cast<SharedLocksRequiredAttr>(Attr);
1095
1096 for (SharedLocksRequiredAttr::args_iterator I = SLRAttr->args_begin(),
1097 E = SLRAttr->args_end(); I != E; ++I)
1098 warnIfMutexNotHeld(D, Exp, AK_Read, *I, POK_FunctionCall);
1099 break;
1100 }
1101
1102 case attr::LocksExcluded: {
1103 LocksExcludedAttr *LEAttr = cast<LocksExcludedAttr>(Attr);
1104 for (LocksExcludedAttr::args_iterator I = LEAttr->args_begin(),
1105 E = LEAttr->args_end(); I != E; ++I) {
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001106 MutexID Mutex(*I, Exp, D);
Caitlin Sadowski194418f2011-09-14 20:00:24 +00001107 if (!Mutex.isValid())
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +00001108 MutexID::warnInvalidLock(Handler, *I, Exp, D);
Caitlin Sadowski194418f2011-09-14 20:00:24 +00001109 else if (locksetContains(Mutex))
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001110 Handler.handleFunExcludesLock(D->getName(), Mutex.getName(),
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +00001111 Exp->getExprLoc());
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001112 }
1113 break;
1114 }
1115
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001116 // Ignore other (non thread-safety) attributes
1117 default:
1118 break;
1119 }
1120 }
1121}
1122
DeLesley Hutchinsb4fa4182012-01-06 19:16:50 +00001123
1124/// \brief Add lock to set, if the current block is in the taken branch of a
1125/// trylock.
1126template <class AttrType>
1127void BuildLockset::addTrylock(LockKind LK, AttrType *Attr, Expr *Exp,
1128 NamedDecl *FunDecl, const CFGBlock *PredBlock,
1129 const CFGBlock *CurrBlock, Expr *BrE, bool Neg) {
1130 // Find out which branch has the lock
1131 bool branch = 0;
1132 if (CXXBoolLiteralExpr *BLE = dyn_cast_or_null<CXXBoolLiteralExpr>(BrE)) {
1133 branch = BLE->getValue();
1134 }
1135 else if (IntegerLiteral *ILE = dyn_cast_or_null<IntegerLiteral>(BrE)) {
1136 branch = ILE->getValue().getBoolValue();
1137 }
1138 int branchnum = branch ? 0 : 1;
1139 if (Neg) branchnum = !branchnum;
1140
1141 // If we've taken the trylock branch, then add the lock
1142 int i = 0;
1143 for (CFGBlock::const_succ_iterator SI = PredBlock->succ_begin(),
1144 SE = PredBlock->succ_end(); SI != SE && i < 2; ++SI, ++i) {
1145 if (*SI == CurrBlock && i == branchnum) {
1146 addLocksToSet(LK, Attr, Exp, FunDecl, 0);
1147 }
1148 }
1149}
1150
1151
1152// If Cond can be traced back to a function call, return the call expression.
1153// The negate variable should be called with false, and will be set to true
1154// if the function call is negated, e.g. if (!mu.tryLock(...))
1155CallExpr* BuildLockset::getTrylockCallExpr(Stmt *Cond,
1156 LocalVariableMap::Context C,
1157 bool &Negate) {
1158 if (!Cond)
1159 return 0;
1160
1161 if (CallExpr *CallExp = dyn_cast<CallExpr>(Cond)) {
1162 return CallExp;
1163 }
1164 else if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(Cond)) {
1165 return getTrylockCallExpr(CE->getSubExpr(), C, Negate);
1166 }
1167 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Cond)) {
1168 Expr *E = LocalVarMap.lookupExpr(DRE->getDecl(), C);
1169 return getTrylockCallExpr(E, C, Negate);
1170 }
1171 else if (UnaryOperator *UOP = dyn_cast<UnaryOperator>(Cond)) {
1172 if (UOP->getOpcode() == UO_LNot) {
1173 Negate = !Negate;
1174 return getTrylockCallExpr(UOP->getSubExpr(), C, Negate);
1175 }
1176 }
1177 // FIXME -- handle && and || as well.
1178 return NULL;
1179}
1180
1181
1182/// \brief Process a conditional branch from a previous block to the current
1183/// block, looking for trylock calls.
1184void BuildLockset::handleTrylock(Stmt *Cond, const CFGBlock *PredBlock,
1185 const CFGBlock *CurrBlock) {
1186 bool Negate = false;
1187 CallExpr *Exp = getTrylockCallExpr(Cond, LVarCtx, Negate);
1188 if (!Exp)
1189 return;
1190
1191 NamedDecl *FunDecl = dyn_cast_or_null<NamedDecl>(Exp->getCalleeDecl());
1192 if(!FunDecl || !FunDecl->hasAttrs())
1193 return;
1194
1195 // If the condition is a call to a Trylock function, then grab the attributes
1196 AttrVec &ArgAttrs = FunDecl->getAttrs();
1197 for (unsigned i = 0; i < ArgAttrs.size(); ++i) {
1198 Attr *Attr = ArgAttrs[i];
1199 switch (Attr->getKind()) {
1200 case attr::ExclusiveTrylockFunction: {
1201 ExclusiveTrylockFunctionAttr *A =
1202 cast<ExclusiveTrylockFunctionAttr>(Attr);
1203 addTrylock(LK_Exclusive, A, Exp, FunDecl, PredBlock, CurrBlock,
1204 A->getSuccessValue(), Negate);
1205 break;
1206 }
1207 case attr::SharedTrylockFunction: {
1208 SharedTrylockFunctionAttr *A =
1209 cast<SharedTrylockFunctionAttr>(Attr);
1210 addTrylock(LK_Shared, A, Exp, FunDecl, PredBlock, CurrBlock,
1211 A->getSuccessValue(), Negate);
1212 break;
1213 }
1214 default:
1215 break;
1216 }
1217 }
1218}
1219
1220
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +00001221/// \brief For unary operations which read and write a variable, we need to
1222/// check whether we hold any required mutexes. Reads are checked in
1223/// VisitCastExpr.
1224void BuildLockset::VisitUnaryOperator(UnaryOperator *UO) {
1225 switch (UO->getOpcode()) {
1226 case clang::UO_PostDec:
1227 case clang::UO_PostInc:
1228 case clang::UO_PreDec:
1229 case clang::UO_PreInc: {
1230 Expr *SubExp = UO->getSubExpr()->IgnoreParenCasts();
1231 checkAccess(SubExp, AK_Written);
1232 checkDereference(SubExp, AK_Written);
1233 break;
1234 }
1235 default:
1236 break;
1237 }
1238}
1239
1240/// For binary operations which assign to a variable (writes), we need to check
1241/// whether we hold any required mutexes.
1242/// FIXME: Deal with non-primitive types.
1243void BuildLockset::VisitBinaryOperator(BinaryOperator *BO) {
1244 if (!BO->isAssignmentOp())
1245 return;
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001246
1247 // adjust the context
1248 LVarCtx = LocalVarMap.getNextContext(CtxIndex, BO, LVarCtx);
1249
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +00001250 Expr *LHSExp = BO->getLHS()->IgnoreParenCasts();
1251 checkAccess(LHSExp, AK_Written);
1252 checkDereference(LHSExp, AK_Written);
1253}
1254
1255/// Whenever we do an LValue to Rvalue cast, we are reading a variable and
1256/// need to ensure we hold any required mutexes.
1257/// FIXME: Deal with non-primitive types.
1258void BuildLockset::VisitCastExpr(CastExpr *CE) {
1259 if (CE->getCastKind() != CK_LValueToRValue)
1260 return;
1261 Expr *SubExp = CE->getSubExpr()->IgnoreParenCasts();
1262 checkAccess(SubExp, AK_Read);
1263 checkDereference(SubExp, AK_Read);
1264}
1265
1266
DeLesley Hutchinsdf497822011-12-29 00:56:48 +00001267void BuildLockset::VisitCallExpr(CallExpr *Exp) {
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +00001268 NamedDecl *D = dyn_cast_or_null<NamedDecl>(Exp->getCalleeDecl());
1269 if(!D || !D->hasAttrs())
1270 return;
1271 handleCall(Exp, D);
1272}
1273
1274void BuildLockset::VisitCXXConstructExpr(CXXConstructExpr *Exp) {
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +00001275 // FIXME -- only handles constructors in DeclStmt below.
1276}
1277
1278void BuildLockset::VisitDeclStmt(DeclStmt *S) {
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001279 // adjust the context
1280 LVarCtx = LocalVarMap.getNextContext(CtxIndex, S, LVarCtx);
1281
DeLesley Hutchins1fa3c062011-12-08 20:23:06 +00001282 DeclGroupRef DGrp = S->getDeclGroup();
1283 for (DeclGroupRef::iterator I = DGrp.begin(), E = DGrp.end(); I != E; ++I) {
1284 Decl *D = *I;
1285 if (VarDecl *VD = dyn_cast_or_null<VarDecl>(D)) {
1286 Expr *E = VD->getInit();
1287 if (CXXConstructExpr *CE = dyn_cast_or_null<CXXConstructExpr>(E)) {
1288 NamedDecl *CtorD = dyn_cast_or_null<NamedDecl>(CE->getConstructor());
1289 if (!CtorD || !CtorD->hasAttrs())
1290 return;
1291 handleCall(CE, CtorD, VD);
1292 }
1293 }
1294 }
DeLesley Hutchinse0eaa852011-10-21 18:06:53 +00001295}
1296
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001297
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +00001298/// \brief Compute the intersection of two locksets and issue warnings for any
1299/// locks in the symmetric difference.
1300///
1301/// This function is used at a merge point in the CFG when comparing the lockset
1302/// of each branch being merged. For example, given the following sequence:
1303/// A; if () then B; else C; D; we need to check that the lockset after B and C
1304/// are the same. In the event of a difference, we use the intersection of these
1305/// two locksets at the start of D.
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001306Lockset ThreadSafetyAnalyzer::intersectAndWarn(const Lockset LSet1,
1307 const Lockset LSet2,
1308 LockErrorKind LEK) {
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +00001309 Lockset Intersection = LSet1;
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001310 for (Lockset::iterator I = LSet2.begin(), E = LSet2.end(); I != E; ++I) {
1311 const MutexID &LSet2Mutex = I.getKey();
1312 const LockData &LSet2LockData = I.getData();
1313 if (const LockData *LD = LSet1.lookup(LSet2Mutex)) {
1314 if (LD->LKind != LSet2LockData.LKind) {
1315 Handler.handleExclusiveAndShared(LSet2Mutex.getName(),
1316 LSet2LockData.AcquireLoc,
1317 LD->AcquireLoc);
1318 if (LD->LKind != LK_Exclusive)
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001319 Intersection = LocksetFactory.add(Intersection, LSet2Mutex,
1320 LSet2LockData);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001321 }
1322 } else {
1323 Handler.handleMutexHeldEndOfScope(LSet2Mutex.getName(),
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +00001324 LSet2LockData.AcquireLoc, LEK);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001325 }
1326 }
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001327
1328 for (Lockset::iterator I = LSet1.begin(), E = LSet1.end(); I != E; ++I) {
1329 if (!LSet2.contains(I.getKey())) {
1330 const MutexID &Mutex = I.getKey();
1331 const LockData &MissingLock = I.getData();
1332 Handler.handleMutexHeldEndOfScope(Mutex.getName(),
Caitlin Sadowski4e4bc752011-09-15 17:25:19 +00001333 MissingLock.AcquireLoc, LEK);
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001334 Intersection = LocksetFactory.remove(Intersection, Mutex);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001335 }
1336 }
1337 return Intersection;
1338}
1339
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001340Lockset ThreadSafetyAnalyzer::addLock(Lockset &LSet, Expr *MutexExp,
1341 const NamedDecl *D,
1342 LockKind LK, SourceLocation Loc) {
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001343 MutexID Mutex(MutexExp, 0, D);
Caitlin Sadowskicb967512011-09-15 17:43:08 +00001344 if (!Mutex.isValid()) {
DeLesley Hutchinsf1ac6372011-10-21 18:10:14 +00001345 MutexID::warnInvalidLock(Handler, MutexExp, 0, D);
Caitlin Sadowskicb967512011-09-15 17:43:08 +00001346 return LSet;
1347 }
1348 LockData NewLock(Loc, LK);
1349 return LocksetFactory.add(LSet, Mutex, NewLock);
1350}
1351
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001352/// \brief Check a function's CFG for thread-safety violations.
1353///
1354/// We traverse the blocks in the CFG, compute the set of mutexes that are held
1355/// at the end of each block, and issue warnings for thread safety violations.
1356/// Each block in the CFG is traversed exactly once.
Ted Kremenek1d26f482011-10-24 01:32:45 +00001357void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) {
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001358 CFG *CFGraph = AC.getCFG();
1359 if (!CFGraph) return;
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001360 const NamedDecl *D = dyn_cast_or_null<NamedDecl>(AC.getDecl());
1361
1362 if (!D)
1363 return; // Ignore anonymous functions for now.
1364 if (D->getAttr<NoThreadSafetyAnalysisAttr>())
1365 return;
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001366
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001367 std::vector<CFGBlockInfo> BlockInfo(CFGraph->getNumBlockIDs(),
1368 CFGBlockInfo::getEmptyBlockInfo(LocksetFactory, LocalVarMap));
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001369
1370 // We need to explore the CFG via a "topological" ordering.
1371 // That way, we will be guaranteed to have information about required
1372 // predecessor locksets when exploring a new block.
Ted Kremenek439ed162011-10-22 02:14:27 +00001373 PostOrderCFGView *SortedGraph = AC.getAnalysis<PostOrderCFGView>();
1374 PostOrderCFGView::CFGBlockSet VisitedBlocks(CFGraph);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001375
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001376 // Compute SSA names for local variables
1377 LocalVarMap.traverseCFG(CFGraph, SortedGraph, BlockInfo);
1378
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001379 // Add locks from exclusive_locks_required and shared_locks_required
1380 // to initial lockset.
Ted Kremenek439ed162011-10-22 02:14:27 +00001381 if (!SortedGraph->empty() && D->hasAttrs()) {
1382 const CFGBlock *FirstBlock = *SortedGraph->begin();
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001383 Lockset &InitialLockset = BlockInfo[FirstBlock->getBlockID()].EntrySet;
Caitlin Sadowskicb967512011-09-15 17:43:08 +00001384 const AttrVec &ArgAttrs = D->getAttrs();
1385 for(unsigned i = 0; i < ArgAttrs.size(); ++i) {
1386 Attr *Attr = ArgAttrs[i];
Caitlin Sadowski1748b122011-09-16 00:35:54 +00001387 SourceLocation AttrLoc = Attr->getLocation();
Caitlin Sadowskicb967512011-09-15 17:43:08 +00001388 if (SharedLocksRequiredAttr *SLRAttr
1389 = dyn_cast<SharedLocksRequiredAttr>(Attr)) {
1390 for (SharedLocksRequiredAttr::args_iterator
1391 SLRIter = SLRAttr->args_begin(),
1392 SLREnd = SLRAttr->args_end(); SLRIter != SLREnd; ++SLRIter)
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001393 InitialLockset = addLock(InitialLockset,
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001394 *SLRIter, D, LK_Shared,
Caitlin Sadowski1748b122011-09-16 00:35:54 +00001395 AttrLoc);
Caitlin Sadowskicb967512011-09-15 17:43:08 +00001396 } else if (ExclusiveLocksRequiredAttr *ELRAttr
1397 = dyn_cast<ExclusiveLocksRequiredAttr>(Attr)) {
1398 for (ExclusiveLocksRequiredAttr::args_iterator
1399 ELRIter = ELRAttr->args_begin(),
1400 ELREnd = ELRAttr->args_end(); ELRIter != ELREnd; ++ELRIter)
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001401 InitialLockset = addLock(InitialLockset,
DeLesley Hutchins9f80a972011-10-17 21:33:35 +00001402 *ELRIter, D, LK_Exclusive,
Caitlin Sadowski1748b122011-09-16 00:35:54 +00001403 AttrLoc);
Caitlin Sadowskicb967512011-09-15 17:43:08 +00001404 }
1405 }
1406 }
1407
Ted Kremenek439ed162011-10-22 02:14:27 +00001408 for (PostOrderCFGView::iterator I = SortedGraph->begin(),
1409 E = SortedGraph->end(); I!= E; ++I) {
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001410 const CFGBlock *CurrBlock = *I;
1411 int CurrBlockID = CurrBlock->getBlockID();
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001412 CFGBlockInfo *CurrBlockInfo = &BlockInfo[CurrBlockID];
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001413
1414 // Use the default initial lockset in case there are no predecessors.
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001415 VisitedBlocks.insert(CurrBlock);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001416
1417 // Iterate through the predecessor blocks and warn if the lockset for all
1418 // predecessors is not the same. We take the entry lockset of the current
1419 // block to be the intersection of all previous locksets.
1420 // FIXME: By keeping the intersection, we may output more errors in future
1421 // for a lock which is not in the intersection, but was in the union. We
1422 // may want to also keep the union in future. As an example, let's say
1423 // the intersection contains Mutex L, and the union contains L and M.
1424 // Later we unlock M. At this point, we would output an error because we
1425 // never locked M; although the real error is probably that we forgot to
1426 // lock M on all code paths. Conversely, let's say that later we lock M.
1427 // In this case, we should compare against the intersection instead of the
1428 // union because the real error is probably that we forgot to unlock M on
1429 // all code paths.
1430 bool LocksetInitialized = false;
1431 for (CFGBlock::const_pred_iterator PI = CurrBlock->pred_begin(),
1432 PE = CurrBlock->pred_end(); PI != PE; ++PI) {
1433
1434 // if *PI -> CurrBlock is a back edge
1435 if (*PI == 0 || !VisitedBlocks.alreadySet(*PI))
1436 continue;
1437
1438 int PrevBlockID = (*PI)->getBlockID();
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001439 CFGBlockInfo *PrevBlockInfo = &BlockInfo[PrevBlockID];
1440
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001441 if (!LocksetInitialized) {
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001442 CurrBlockInfo->EntrySet = PrevBlockInfo->ExitSet;
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001443 LocksetInitialized = true;
1444 } else {
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001445 CurrBlockInfo->EntrySet =
1446 intersectAndWarn(CurrBlockInfo->EntrySet, PrevBlockInfo->ExitSet,
1447 LEK_LockedSomePredecessors);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001448 }
1449 }
1450
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001451 BuildLockset LocksetBuilder(this, *CurrBlockInfo);
DeLesley Hutchinsb4fa4182012-01-06 19:16:50 +00001452 CFGBlock::const_pred_iterator PI = CurrBlock->pred_begin(),
1453 PE = CurrBlock->pred_end();
1454 if (PI != PE) {
1455 // If the predecessor ended in a branch, then process any trylocks.
1456 // FIXME -- check to make sure there's only one predecessor.
1457 if (Stmt *TCE = (*PI)->getTerminatorCondition()) {
1458 LocksetBuilder.handleTrylock(TCE, *PI, CurrBlock);
1459 }
1460 }
1461
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001462 // Visit all the statements in the basic block.
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001463 for (CFGBlock::const_iterator BI = CurrBlock->begin(),
1464 BE = CurrBlock->end(); BI != BE; ++BI) {
DeLesley Hutchins6db51f72011-10-21 20:51:27 +00001465 switch (BI->getKind()) {
1466 case CFGElement::Statement: {
1467 const CFGStmt *CS = cast<CFGStmt>(&*BI);
1468 LocksetBuilder.Visit(const_cast<Stmt*>(CS->getStmt()));
1469 break;
1470 }
1471 // Ignore BaseDtor, MemberDtor, and TemporaryDtor for now.
1472 case CFGElement::AutomaticObjectDtor: {
1473 const CFGAutomaticObjDtor *AD = cast<CFGAutomaticObjDtor>(&*BI);
1474 CXXDestructorDecl *DD = const_cast<CXXDestructorDecl*>(
1475 AD->getDestructorDecl(AC.getASTContext()));
1476 if (!DD->hasAttrs())
1477 break;
1478
1479 // Create a dummy expression,
1480 VarDecl *VD = const_cast<VarDecl*>(AD->getVarDecl());
1481 DeclRefExpr DRE(VD, VD->getType(), VK_LValue,
1482 AD->getTriggerStmt()->getLocEnd());
1483 LocksetBuilder.handleCall(&DRE, DD);
1484 break;
1485 }
1486 default:
1487 break;
1488 }
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001489 }
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001490 CurrBlockInfo->ExitSet = LocksetBuilder.LSet;
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001491
1492 // For every back edge from CurrBlock (the end of the loop) to another block
1493 // (FirstLoopBlock) we need to check that the Lockset of Block is equal to
1494 // the one held at the beginning of FirstLoopBlock. We can look up the
1495 // Lockset held at the beginning of FirstLoopBlock in the EntryLockSets map.
1496 for (CFGBlock::const_succ_iterator SI = CurrBlock->succ_begin(),
1497 SE = CurrBlock->succ_end(); SI != SE; ++SI) {
1498
1499 // if CurrBlock -> *SI is *not* a back edge
1500 if (*SI == 0 || !VisitedBlocks.alreadySet(*SI))
1501 continue;
1502
1503 CFGBlock *FirstLoopBlock = *SI;
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001504 Lockset PreLoop = BlockInfo[FirstLoopBlock->getBlockID()].EntrySet;
1505 Lockset LoopEnd = BlockInfo[CurrBlockID].ExitSet;
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001506 intersectAndWarn(LoopEnd, PreLoop, LEK_LockedSomeLoopIterations);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001507 }
1508 }
1509
DeLesley Hutchinsb37d2b52012-01-06 18:36:09 +00001510 Lockset InitialLockset = BlockInfo[CFGraph->getEntry().getBlockID()].EntrySet;
1511 Lockset FinalLockset = BlockInfo[CFGraph->getExit().getBlockID()].ExitSet;
Caitlin Sadowski1748b122011-09-16 00:35:54 +00001512
1513 // FIXME: Should we call this function for all blocks which exit the function?
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001514 intersectAndWarn(InitialLockset, FinalLockset, LEK_LockedAtEndOfFunction);
1515}
1516
1517} // end anonymous namespace
1518
1519
1520namespace clang {
1521namespace thread_safety {
1522
1523/// \brief Check a function's CFG for thread-safety violations.
1524///
1525/// We traverse the blocks in the CFG, compute the set of mutexes that are held
1526/// at the end of each block, and issue warnings for thread safety violations.
1527/// Each block in the CFG is traversed exactly once.
Ted Kremenek1d26f482011-10-24 01:32:45 +00001528void runThreadSafetyAnalysis(AnalysisDeclContext &AC,
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001529 ThreadSafetyHandler &Handler) {
1530 ThreadSafetyAnalyzer Analyzer(Handler);
1531 Analyzer.runAnalysis(AC);
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001532}
1533
1534/// \brief Helper function that returns a LockKind required for the given level
1535/// of access.
1536LockKind getLockKindFromAccessKind(AccessKind AK) {
1537 switch (AK) {
1538 case AK_Read :
1539 return LK_Shared;
1540 case AK_Written :
1541 return LK_Exclusive;
1542 }
Benjamin Kramerafc5b152011-09-10 21:52:04 +00001543 llvm_unreachable("Unknown AccessKind");
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001544}
DeLesley Hutchinsa60448d2011-10-21 16:14:33 +00001545
Caitlin Sadowski402aa062011-09-09 16:11:56 +00001546}} // end namespace clang::thread_safety