clang API Documentation

ThreadSafety.cpp
Go to the documentation of this file.
00001 //===- ThreadSafety.cpp ----------------------------------------*- C++ --*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // A intra-procedural analysis for thread safety (e.g. deadlocks and race
00011 // conditions), based off of an annotation system.
00012 //
00013 // See http://clang.llvm.org/docs/LanguageExtensions.html#threadsafety for more
00014 // information.
00015 //
00016 //===----------------------------------------------------------------------===//
00017 
00018 #include "clang/Analysis/Analyses/ThreadSafety.h"
00019 #include "clang/Analysis/Analyses/PostOrderCFGView.h"
00020 #include "clang/Analysis/AnalysisContext.h"
00021 #include "clang/Analysis/CFG.h"
00022 #include "clang/Analysis/CFGStmtMap.h"
00023 #include "clang/AST/DeclCXX.h"
00024 #include "clang/AST/ExprCXX.h"
00025 #include "clang/AST/StmtCXX.h"
00026 #include "clang/AST/StmtVisitor.h"
00027 #include "clang/Basic/SourceManager.h"
00028 #include "clang/Basic/SourceLocation.h"
00029 #include "llvm/ADT/BitVector.h"
00030 #include "llvm/ADT/FoldingSet.h"
00031 #include "llvm/ADT/ImmutableMap.h"
00032 #include "llvm/ADT/PostOrderIterator.h"
00033 #include "llvm/ADT/SmallVector.h"
00034 #include "llvm/ADT/StringRef.h"
00035 #include "llvm/Support/raw_ostream.h"
00036 #include <algorithm>
00037 #include <utility>
00038 #include <vector>
00039 
00040 using namespace clang;
00041 using namespace thread_safety;
00042 
00043 // Key method definition
00044 ThreadSafetyHandler::~ThreadSafetyHandler() {}
00045 
00046 namespace {
00047 
00048 /// \brief A MutexID object uniquely identifies a particular mutex, and
00049 /// is built from an Expr* (i.e. calling a lock function).
00050 ///
00051 /// Thread-safety analysis works by comparing lock expressions.  Within the
00052 /// body of a function, an expression such as "x->foo->bar.mu" will resolve to
00053 /// a particular mutex object at run-time.  Subsequent occurrences of the same
00054 /// expression (where "same" means syntactic equality) will refer to the same
00055 /// run-time object if three conditions hold:
00056 /// (1) Local variables in the expression, such as "x" have not changed.
00057 /// (2) Values on the heap that affect the expression have not changed.
00058 /// (3) The expression involves only pure function calls.
00059 ///
00060 /// The current implementation assumes, but does not verify, that multiple uses
00061 /// of the same lock expression satisfies these criteria.
00062 ///
00063 /// Clang introduces an additional wrinkle, which is that it is difficult to
00064 /// derive canonical expressions, or compare expressions directly for equality.
00065 /// Thus, we identify a mutex not by an Expr, but by the list of named
00066 /// declarations that are referenced by the Expr.  In other words,
00067 /// x->foo->bar.mu will be a four element vector with the Decls for
00068 /// mu, bar, and foo, and x.  The vector will uniquely identify the expression
00069 /// for all practical purposes.  Null is used to denote 'this'.
00070 ///
00071 /// Note we will need to perform substitution on "this" and function parameter
00072 /// names when constructing a lock expression.
00073 ///
00074 /// For example:
00075 /// class C { Mutex Mu;  void lock() EXCLUSIVE_LOCK_FUNCTION(this->Mu); };
00076 /// void myFunc(C *X) { ... X->lock() ... }
00077 /// The original expression for the mutex acquired by myFunc is "this->Mu", but
00078 /// "X" is substituted for "this" so we get X->Mu();
00079 ///
00080 /// For another example:
00081 /// foo(MyList *L) EXCLUSIVE_LOCKS_REQUIRED(L->Mu) { ... }
00082 /// MyList *MyL;
00083 /// foo(MyL);  // requires lock MyL->Mu to be held
00084 class MutexID {
00085   SmallVector<NamedDecl*, 2> DeclSeq;
00086 
00087   /// Build a Decl sequence representing the lock from the given expression.
00088   /// Recursive function that terminates on DeclRefExpr.
00089   /// Note: this function merely creates a MutexID; it does not check to
00090   /// ensure that the original expression is a valid mutex expression.
00091   void buildMutexID(Expr *Exp, const NamedDecl *D, Expr *Parent,
00092                     unsigned NumArgs, Expr **FunArgs) {
00093     if (!Exp) {
00094       DeclSeq.clear();
00095       return;
00096     }
00097 
00098     if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Exp)) {
00099       NamedDecl *ND = cast<NamedDecl>(DRE->getDecl()->getCanonicalDecl());
00100       ParmVarDecl *PV = dyn_cast_or_null<ParmVarDecl>(ND);
00101       if (PV) {
00102         FunctionDecl *FD =
00103           cast<FunctionDecl>(PV->getDeclContext())->getCanonicalDecl();
00104         unsigned i = PV->getFunctionScopeIndex();
00105 
00106         if (FunArgs && FD == D->getCanonicalDecl()) {
00107           // Substitute call arguments for references to function parameters
00108           assert(i < NumArgs);
00109           buildMutexID(FunArgs[i], D, 0, 0, 0);
00110           return;
00111         }
00112         // Map the param back to the param of the original function declaration.
00113         DeclSeq.push_back(FD->getParamDecl(i));
00114         return;
00115       }
00116       // Not a function parameter -- just store the reference.
00117       DeclSeq.push_back(ND);
00118     } else if (MemberExpr *ME = dyn_cast<MemberExpr>(Exp)) {
00119       NamedDecl *ND = ME->getMemberDecl();
00120       DeclSeq.push_back(ND);
00121       buildMutexID(ME->getBase(), D, Parent, NumArgs, FunArgs);
00122     } else if (isa<CXXThisExpr>(Exp)) {
00123       if (Parent)
00124         buildMutexID(Parent, D, 0, 0, 0);
00125       else {
00126         DeclSeq.push_back(0);  // Use 0 to represent 'this'.
00127         return;  // mutexID is still valid in this case
00128       }
00129     } else if (CXXMemberCallExpr *CMCE = dyn_cast<CXXMemberCallExpr>(Exp)) {
00130       DeclSeq.push_back(CMCE->getMethodDecl()->getCanonicalDecl());
00131       buildMutexID(CMCE->getImplicitObjectArgument(),
00132                    D, Parent, NumArgs, FunArgs);
00133       unsigned NumCallArgs = CMCE->getNumArgs();
00134       Expr** CallArgs = CMCE->getArgs();
00135       for (unsigned i = 0; i < NumCallArgs; ++i) {
00136         buildMutexID(CallArgs[i], D, Parent, NumArgs, FunArgs);
00137       }
00138     } else if (CallExpr *CE = dyn_cast<CallExpr>(Exp)) {
00139       buildMutexID(CE->getCallee(), D, Parent, NumArgs, FunArgs);
00140       unsigned NumCallArgs = CE->getNumArgs();
00141       Expr** CallArgs = CE->getArgs();
00142       for (unsigned i = 0; i < NumCallArgs; ++i) {
00143         buildMutexID(CallArgs[i], D, Parent, NumArgs, FunArgs);
00144       }
00145     } else if (BinaryOperator *BOE = dyn_cast<BinaryOperator>(Exp)) {
00146       buildMutexID(BOE->getLHS(), D, Parent, NumArgs, FunArgs);
00147       buildMutexID(BOE->getRHS(), D, Parent, NumArgs, FunArgs);
00148     } else if (UnaryOperator *UOE = dyn_cast<UnaryOperator>(Exp)) {
00149       buildMutexID(UOE->getSubExpr(), D, Parent, NumArgs, FunArgs);
00150     } else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(Exp)) {
00151       buildMutexID(ASE->getBase(), D, Parent, NumArgs, FunArgs);
00152       buildMutexID(ASE->getIdx(), D, Parent, NumArgs, FunArgs);
00153     } else if (AbstractConditionalOperator *CE =
00154                  dyn_cast<AbstractConditionalOperator>(Exp)) {
00155       buildMutexID(CE->getCond(), D, Parent, NumArgs, FunArgs);
00156       buildMutexID(CE->getTrueExpr(), D, Parent, NumArgs, FunArgs);
00157       buildMutexID(CE->getFalseExpr(), D, Parent, NumArgs, FunArgs);
00158     } else if (ChooseExpr *CE = dyn_cast<ChooseExpr>(Exp)) {
00159       buildMutexID(CE->getCond(), D, Parent, NumArgs, FunArgs);
00160       buildMutexID(CE->getLHS(), D, Parent, NumArgs, FunArgs);
00161       buildMutexID(CE->getRHS(), D, Parent, NumArgs, FunArgs);
00162     } else if (CastExpr *CE = dyn_cast<CastExpr>(Exp)) {
00163       buildMutexID(CE->getSubExpr(), D, Parent, NumArgs, FunArgs);
00164     } else if (ParenExpr *PE = dyn_cast<ParenExpr>(Exp)) {
00165       buildMutexID(PE->getSubExpr(), D, Parent, NumArgs, FunArgs);
00166     } else if (isa<CharacterLiteral>(Exp) ||
00167              isa<CXXNullPtrLiteralExpr>(Exp) ||
00168              isa<GNUNullExpr>(Exp) ||
00169              isa<CXXBoolLiteralExpr>(Exp) ||
00170              isa<FloatingLiteral>(Exp) ||
00171              isa<ImaginaryLiteral>(Exp) ||
00172              isa<IntegerLiteral>(Exp) ||
00173              isa<StringLiteral>(Exp) ||
00174              isa<ObjCStringLiteral>(Exp)) {
00175       return;  // FIXME: Ignore literals for now
00176     } else {
00177       // Ignore.  FIXME: mark as invalid expression?
00178     }
00179   }
00180 
00181   /// \brief Construct a MutexID from an expression.
00182   /// \param MutexExp The original mutex expression within an attribute
00183   /// \param DeclExp An expression involving the Decl on which the attribute
00184   ///        occurs.
00185   /// \param D  The declaration to which the lock/unlock attribute is attached.
00186   void buildMutexIDFromExp(Expr *MutexExp, Expr *DeclExp, const NamedDecl *D) {
00187     Expr *Parent = 0;
00188     unsigned NumArgs = 0;
00189     Expr **FunArgs = 0;
00190 
00191     // If we are processing a raw attribute expression, with no substitutions.
00192     if (DeclExp == 0) {
00193       buildMutexID(MutexExp, D, 0, 0, 0);
00194       return;
00195     }
00196 
00197     // Examine DeclExp to find Parent and FunArgs, which are used to substitute
00198     // for formal parameters when we call buildMutexID later.
00199     if (MemberExpr *ME = dyn_cast<MemberExpr>(DeclExp)) {
00200       Parent = ME->getBase();
00201     } else if (CXXMemberCallExpr *CE = dyn_cast<CXXMemberCallExpr>(DeclExp)) {
00202       Parent = CE->getImplicitObjectArgument();
00203       NumArgs = CE->getNumArgs();
00204       FunArgs = CE->getArgs();
00205     } else if (CallExpr *CE = dyn_cast<CallExpr>(DeclExp)) {
00206       NumArgs = CE->getNumArgs();
00207       FunArgs = CE->getArgs();
00208     } else if (CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(DeclExp)) {
00209       Parent = 0;  // FIXME -- get the parent from DeclStmt
00210       NumArgs = CE->getNumArgs();
00211       FunArgs = CE->getArgs();
00212     } else if (D && isa<CXXDestructorDecl>(D)) {
00213       // There's no such thing as a "destructor call" in the AST.
00214       Parent = DeclExp;
00215     }
00216 
00217     // If the attribute has no arguments, then assume the argument is "this".
00218     if (MutexExp == 0) {
00219       buildMutexID(Parent, D, 0, 0, 0);
00220       return;
00221     }
00222 
00223     buildMutexID(MutexExp, D, Parent, NumArgs, FunArgs);
00224   }
00225 
00226 public:
00227   explicit MutexID(clang::Decl::EmptyShell e) {
00228     DeclSeq.clear();
00229   }
00230 
00231   /// \param MutexExp The original mutex expression within an attribute
00232   /// \param DeclExp An expression involving the Decl on which the attribute
00233   ///        occurs.
00234   /// \param D  The declaration to which the lock/unlock attribute is attached.
00235   /// Caller must check isValid() after construction.
00236   MutexID(Expr* MutexExp, Expr *DeclExp, const NamedDecl* D) {
00237     buildMutexIDFromExp(MutexExp, DeclExp, D);
00238   }
00239 
00240   /// Return true if this is a valid decl sequence.
00241   /// Caller must call this by hand after construction to handle errors.
00242   bool isValid() const {
00243     return !DeclSeq.empty();
00244   }
00245 
00246   /// Issue a warning about an invalid lock expression
00247   static void warnInvalidLock(ThreadSafetyHandler &Handler, Expr* MutexExp,
00248                               Expr *DeclExp, const NamedDecl* D) {
00249     SourceLocation Loc;
00250     if (DeclExp)
00251       Loc = DeclExp->getExprLoc();
00252 
00253     // FIXME: add a note about the attribute location in MutexExp or D
00254     if (Loc.isValid())
00255       Handler.handleInvalidLockExp(Loc);
00256   }
00257 
00258   bool operator==(const MutexID &other) const {
00259     return DeclSeq == other.DeclSeq;
00260   }
00261 
00262   bool operator!=(const MutexID &other) const {
00263     return !(*this == other);
00264   }
00265 
00266   // SmallVector overloads Operator< to do lexicographic ordering. Note that
00267   // we use pointer equality (and <) to compare NamedDecls. This means the order
00268   // of MutexIDs in a lockset is nondeterministic. In order to output
00269   // diagnostics in a deterministic ordering, we must order all diagnostics to
00270   // output by SourceLocation when iterating through this lockset.
00271   bool operator<(const MutexID &other) const {
00272     return DeclSeq < other.DeclSeq;
00273   }
00274 
00275   /// \brief Returns the name of the first Decl in the list for a given MutexID;
00276   /// e.g. the lock expression foo.bar() has name "bar".
00277   /// The caret will point unambiguously to the lock expression, so using this
00278   /// name in diagnostics is a way to get simple, and consistent, mutex names.
00279   /// We do not want to output the entire expression text for security reasons.
00280   std::string getName() const {
00281     assert(isValid());
00282     if (!DeclSeq.front())
00283       return "this";  // Use 0 to represent 'this'.
00284     return DeclSeq.front()->getNameAsString();
00285   }
00286 
00287   void Profile(llvm::FoldingSetNodeID &ID) const {
00288     for (SmallVectorImpl<NamedDecl*>::const_iterator I = DeclSeq.begin(),
00289          E = DeclSeq.end(); I != E; ++I) {
00290       ID.AddPointer(*I);
00291     }
00292   }
00293 };
00294 
00295 
00296 /// \brief This is a helper class that stores info about the most recent
00297 /// accquire of a Lock.
00298 ///
00299 /// The main body of the analysis maps MutexIDs to LockDatas.
00300 struct LockData {
00301   SourceLocation AcquireLoc;
00302 
00303   /// \brief LKind stores whether a lock is held shared or exclusively.
00304   /// Note that this analysis does not currently support either re-entrant
00305   /// locking or lock "upgrading" and "downgrading" between exclusive and
00306   /// shared.
00307   ///
00308   /// FIXME: add support for re-entrant locking and lock up/downgrading
00309   LockKind LKind;
00310   MutexID UnderlyingMutex;  // for ScopedLockable objects
00311 
00312   LockData(SourceLocation AcquireLoc, LockKind LKind)
00313     : AcquireLoc(AcquireLoc), LKind(LKind), UnderlyingMutex(Decl::EmptyShell())
00314   {}
00315 
00316   LockData(SourceLocation AcquireLoc, LockKind LKind, const MutexID &Mu)
00317     : AcquireLoc(AcquireLoc), LKind(LKind), UnderlyingMutex(Mu) {}
00318 
00319   bool operator==(const LockData &other) const {
00320     return AcquireLoc == other.AcquireLoc && LKind == other.LKind;
00321   }
00322 
00323   bool operator!=(const LockData &other) const {
00324     return !(*this == other);
00325   }
00326 
00327   void Profile(llvm::FoldingSetNodeID &ID) const {
00328     ID.AddInteger(AcquireLoc.getRawEncoding());
00329     ID.AddInteger(LKind);
00330   }
00331 };
00332 
00333 
00334 /// A Lockset maps each MutexID (defined above) to information about how it has
00335 /// been locked.
00336 typedef llvm::ImmutableMap<MutexID, LockData> Lockset;
00337 typedef llvm::ImmutableMap<const NamedDecl*, unsigned> LocalVarContext;
00338 
00339 class LocalVariableMap;
00340 
00341 /// A side (entry or exit) of a CFG node.
00342 enum CFGBlockSide { CBS_Entry, CBS_Exit };
00343 
00344 /// CFGBlockInfo is a struct which contains all the information that is
00345 /// maintained for each block in the CFG.  See LocalVariableMap for more
00346 /// information about the contexts.
00347 struct CFGBlockInfo {
00348   Lockset EntrySet;             // Lockset held at entry to block
00349   Lockset ExitSet;              // Lockset held at exit from block
00350   LocalVarContext EntryContext; // Context held at entry to block
00351   LocalVarContext ExitContext;  // Context held at exit from block
00352   SourceLocation EntryLoc;      // Location of first statement in block
00353   SourceLocation ExitLoc;       // Location of last statement in block.
00354   unsigned EntryIndex;          // Used to replay contexts later
00355 
00356   const Lockset &getSet(CFGBlockSide Side) const {
00357     return Side == CBS_Entry ? EntrySet : ExitSet;
00358   }
00359   SourceLocation getLocation(CFGBlockSide Side) const {
00360     return Side == CBS_Entry ? EntryLoc : ExitLoc;
00361   }
00362 
00363 private:
00364   CFGBlockInfo(Lockset EmptySet, LocalVarContext EmptyCtx)
00365     : EntrySet(EmptySet), ExitSet(EmptySet),
00366       EntryContext(EmptyCtx), ExitContext(EmptyCtx)
00367   { }
00368 
00369 public:
00370   static CFGBlockInfo getEmptyBlockInfo(Lockset::Factory &F,
00371                                         LocalVariableMap &M);
00372 };
00373 
00374 
00375 
00376 // A LocalVariableMap maintains a map from local variables to their currently
00377 // valid definitions.  It provides SSA-like functionality when traversing the
00378 // CFG.  Like SSA, each definition or assignment to a variable is assigned a
00379 // unique name (an integer), which acts as the SSA name for that definition.
00380 // The total set of names is shared among all CFG basic blocks.
00381 // Unlike SSA, we do not rewrite expressions to replace local variables declrefs
00382 // with their SSA-names.  Instead, we compute a Context for each point in the
00383 // code, which maps local variables to the appropriate SSA-name.  This map
00384 // changes with each assignment.
00385 //
00386 // The map is computed in a single pass over the CFG.  Subsequent analyses can
00387 // then query the map to find the appropriate Context for a statement, and use
00388 // that Context to look up the definitions of variables.
00389 class LocalVariableMap {
00390 public:
00391   typedef LocalVarContext Context;
00392 
00393   /// A VarDefinition consists of an expression, representing the value of the
00394   /// variable, along with the context in which that expression should be
00395   /// interpreted.  A reference VarDefinition does not itself contain this
00396   /// information, but instead contains a pointer to a previous VarDefinition.
00397   struct VarDefinition {
00398   public:
00399     friend class LocalVariableMap;
00400 
00401     const NamedDecl *Dec;  // The original declaration for this variable.
00402     const Expr *Exp;       // The expression for this variable, OR
00403     unsigned Ref;          // Reference to another VarDefinition
00404     Context Ctx;           // The map with which Exp should be interpreted.
00405 
00406     bool isReference() { return !Exp; }
00407 
00408   private:
00409     // Create ordinary variable definition
00410     VarDefinition(const NamedDecl *D, const Expr *E, Context C)
00411       : Dec(D), Exp(E), Ref(0), Ctx(C)
00412     { }
00413 
00414     // Create reference to previous definition
00415     VarDefinition(const NamedDecl *D, unsigned R, Context C)
00416       : Dec(D), Exp(0), Ref(R), Ctx(C)
00417     { }
00418   };
00419 
00420 private:
00421   Context::Factory ContextFactory;
00422   std::vector<VarDefinition> VarDefinitions;
00423   std::vector<unsigned> CtxIndices;
00424   std::vector<std::pair<Stmt*, Context> > SavedContexts;
00425 
00426 public:
00427   LocalVariableMap() {
00428     // index 0 is a placeholder for undefined variables (aka phi-nodes).
00429     VarDefinitions.push_back(VarDefinition(0, 0u, getEmptyContext()));
00430   }
00431 
00432   /// Look up a definition, within the given context.
00433   const VarDefinition* lookup(const NamedDecl *D, Context Ctx) {
00434     const unsigned *i = Ctx.lookup(D);
00435     if (!i)
00436       return 0;
00437     assert(*i < VarDefinitions.size());
00438     return &VarDefinitions[*i];
00439   }
00440 
00441   /// Look up the definition for D within the given context.  Returns
00442   /// NULL if the expression is not statically known.  If successful, also
00443   /// modifies Ctx to hold the context of the return Expr.
00444   const Expr* lookupExpr(const NamedDecl *D, Context &Ctx) {
00445     const unsigned *P = Ctx.lookup(D);
00446     if (!P)
00447       return 0;
00448 
00449     unsigned i = *P;
00450     while (i > 0) {
00451       if (VarDefinitions[i].Exp) {
00452         Ctx = VarDefinitions[i].Ctx;
00453         return VarDefinitions[i].Exp;
00454       }
00455       i = VarDefinitions[i].Ref;
00456     }
00457     return 0;
00458   }
00459 
00460   Context getEmptyContext() { return ContextFactory.getEmptyMap(); }
00461 
00462   /// Return the next context after processing S.  This function is used by
00463   /// clients of the class to get the appropriate context when traversing the
00464   /// CFG.  It must be called for every assignment or DeclStmt.
00465   Context getNextContext(unsigned &CtxIndex, Stmt *S, Context C) {
00466     if (SavedContexts[CtxIndex+1].first == S) {
00467       CtxIndex++;
00468       Context Result = SavedContexts[CtxIndex].second;
00469       return Result;
00470     }
00471     return C;
00472   }
00473 
00474   void dumpVarDefinitionName(unsigned i) {
00475     if (i == 0) {
00476       llvm::errs() << "Undefined";
00477       return;
00478     }
00479     const NamedDecl *Dec = VarDefinitions[i].Dec;
00480     if (!Dec) {
00481       llvm::errs() << "<<NULL>>";
00482       return;
00483     }
00484     Dec->printName(llvm::errs());
00485     llvm::errs() << "." << i << " " << ((void*) Dec);
00486   }
00487 
00488   /// Dumps an ASCII representation of the variable map to llvm::errs()
00489   void dump() {
00490     for (unsigned i = 1, e = VarDefinitions.size(); i < e; ++i) {
00491       const Expr *Exp = VarDefinitions[i].Exp;
00492       unsigned Ref = VarDefinitions[i].Ref;
00493 
00494       dumpVarDefinitionName(i);
00495       llvm::errs() << " = ";
00496       if (Exp) Exp->dump();
00497       else {
00498         dumpVarDefinitionName(Ref);
00499         llvm::errs() << "\n";
00500       }
00501     }
00502   }
00503 
00504   /// Dumps an ASCII representation of a Context to llvm::errs()
00505   void dumpContext(Context C) {
00506     for (Context::iterator I = C.begin(), E = C.end(); I != E; ++I) {
00507       const NamedDecl *D = I.getKey();
00508       D->printName(llvm::errs());
00509       const unsigned *i = C.lookup(D);
00510       llvm::errs() << " -> ";
00511       dumpVarDefinitionName(*i);
00512       llvm::errs() << "\n";
00513     }
00514   }
00515 
00516   /// Builds the variable map.
00517   void traverseCFG(CFG *CFGraph, PostOrderCFGView *SortedGraph,
00518                      std::vector<CFGBlockInfo> &BlockInfo);
00519 
00520 protected:
00521   // Get the current context index
00522   unsigned getContextIndex() { return SavedContexts.size()-1; }
00523 
00524   // Save the current context for later replay
00525   void saveContext(Stmt *S, Context C) {
00526     SavedContexts.push_back(std::make_pair(S,C));
00527   }
00528 
00529   // Adds a new definition to the given context, and returns a new context.
00530   // This method should be called when declaring a new variable.
00531   Context addDefinition(const NamedDecl *D, Expr *Exp, Context Ctx) {
00532     assert(!Ctx.contains(D));
00533     unsigned newID = VarDefinitions.size();
00534     Context NewCtx = ContextFactory.add(Ctx, D, newID);
00535     VarDefinitions.push_back(VarDefinition(D, Exp, Ctx));
00536     return NewCtx;
00537   }
00538 
00539   // Add a new reference to an existing definition.
00540   Context addReference(const NamedDecl *D, unsigned i, Context Ctx) {
00541     unsigned newID = VarDefinitions.size();
00542     Context NewCtx = ContextFactory.add(Ctx, D, newID);
00543     VarDefinitions.push_back(VarDefinition(D, i, Ctx));
00544     return NewCtx;
00545   }
00546 
00547   // Updates a definition only if that definition is already in the map.
00548   // This method should be called when assigning to an existing variable.
00549   Context updateDefinition(const NamedDecl *D, Expr *Exp, Context Ctx) {
00550     if (Ctx.contains(D)) {
00551       unsigned newID = VarDefinitions.size();
00552       Context NewCtx = ContextFactory.remove(Ctx, D);
00553       NewCtx = ContextFactory.add(NewCtx, D, newID);
00554       VarDefinitions.push_back(VarDefinition(D, Exp, Ctx));
00555       return NewCtx;
00556     }
00557     return Ctx;
00558   }
00559 
00560   // Removes a definition from the context, but keeps the variable name
00561   // as a valid variable.  The index 0 is a placeholder for cleared definitions.
00562   Context clearDefinition(const NamedDecl *D, Context Ctx) {
00563     Context NewCtx = Ctx;
00564     if (NewCtx.contains(D)) {
00565       NewCtx = ContextFactory.remove(NewCtx, D);
00566       NewCtx = ContextFactory.add(NewCtx, D, 0);
00567     }
00568     return NewCtx;
00569   }
00570 
00571   // Remove a definition entirely frmo the context.
00572   Context removeDefinition(const NamedDecl *D, Context Ctx) {
00573     Context NewCtx = Ctx;
00574     if (NewCtx.contains(D)) {
00575       NewCtx = ContextFactory.remove(NewCtx, D);
00576     }
00577     return NewCtx;
00578   }
00579 
00580   Context intersectContexts(Context C1, Context C2);
00581   Context createReferenceContext(Context C);
00582   void intersectBackEdge(Context C1, Context C2);
00583 
00584   friend class VarMapBuilder;
00585 };
00586 
00587 
00588 // This has to be defined after LocalVariableMap.
00589 CFGBlockInfo CFGBlockInfo::getEmptyBlockInfo(Lockset::Factory &F,
00590                                              LocalVariableMap &M) {
00591   return CFGBlockInfo(F.getEmptyMap(), M.getEmptyContext());
00592 }
00593 
00594 
00595 /// Visitor which builds a LocalVariableMap
00596 class VarMapBuilder : public StmtVisitor<VarMapBuilder> {
00597 public:
00598   LocalVariableMap* VMap;
00599   LocalVariableMap::Context Ctx;
00600 
00601   VarMapBuilder(LocalVariableMap *VM, LocalVariableMap::Context C)
00602     : VMap(VM), Ctx(C) {}
00603 
00604   void VisitDeclStmt(DeclStmt *S);
00605   void VisitBinaryOperator(BinaryOperator *BO);
00606 };
00607 
00608 
00609 // Add new local variables to the variable map
00610 void VarMapBuilder::VisitDeclStmt(DeclStmt *S) {
00611   bool modifiedCtx = false;
00612   DeclGroupRef DGrp = S->getDeclGroup();
00613   for (DeclGroupRef::iterator I = DGrp.begin(), E = DGrp.end(); I != E; ++I) {
00614     if (VarDecl *VD = dyn_cast_or_null<VarDecl>(*I)) {
00615       Expr *E = VD->getInit();
00616 
00617       // Add local variables with trivial type to the variable map
00618       QualType T = VD->getType();
00619       if (T.isTrivialType(VD->getASTContext())) {
00620         Ctx = VMap->addDefinition(VD, E, Ctx);
00621         modifiedCtx = true;
00622       }
00623     }
00624   }
00625   if (modifiedCtx)
00626     VMap->saveContext(S, Ctx);
00627 }
00628 
00629 // Update local variable definitions in variable map
00630 void VarMapBuilder::VisitBinaryOperator(BinaryOperator *BO) {
00631   if (!BO->isAssignmentOp())
00632     return;
00633 
00634   Expr *LHSExp = BO->getLHS()->IgnoreParenCasts();
00635 
00636   // Update the variable map and current context.
00637   if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(LHSExp)) {
00638     ValueDecl *VDec = DRE->getDecl();
00639     if (Ctx.lookup(VDec)) {
00640       if (BO->getOpcode() == BO_Assign)
00641         Ctx = VMap->updateDefinition(VDec, BO->getRHS(), Ctx);
00642       else
00643         // FIXME -- handle compound assignment operators
00644         Ctx = VMap->clearDefinition(VDec, Ctx);
00645       VMap->saveContext(BO, Ctx);
00646     }
00647   }
00648 }
00649 
00650 
00651 // Computes the intersection of two contexts.  The intersection is the
00652 // set of variables which have the same definition in both contexts;
00653 // variables with different definitions are discarded.
00654 LocalVariableMap::Context
00655 LocalVariableMap::intersectContexts(Context C1, Context C2) {
00656   Context Result = C1;
00657   for (Context::iterator I = C1.begin(), E = C1.end(); I != E; ++I) {
00658     const NamedDecl *Dec = I.getKey();
00659     unsigned i1 = I.getData();
00660     const unsigned *i2 = C2.lookup(Dec);
00661     if (!i2)             // variable doesn't exist on second path
00662       Result = removeDefinition(Dec, Result);
00663     else if (*i2 != i1)  // variable exists, but has different definition
00664       Result = clearDefinition(Dec, Result);
00665   }
00666   return Result;
00667 }
00668 
00669 // For every variable in C, create a new variable that refers to the
00670 // definition in C.  Return a new context that contains these new variables.
00671 // (We use this for a naive implementation of SSA on loop back-edges.)
00672 LocalVariableMap::Context LocalVariableMap::createReferenceContext(Context C) {
00673   Context Result = getEmptyContext();
00674   for (Context::iterator I = C.begin(), E = C.end(); I != E; ++I) {
00675     const NamedDecl *Dec = I.getKey();
00676     unsigned i = I.getData();
00677     Result = addReference(Dec, i, Result);
00678   }
00679   return Result;
00680 }
00681 
00682 // This routine also takes the intersection of C1 and C2, but it does so by
00683 // altering the VarDefinitions.  C1 must be the result of an earlier call to
00684 // createReferenceContext.
00685 void LocalVariableMap::intersectBackEdge(Context C1, Context C2) {
00686   for (Context::iterator I = C1.begin(), E = C1.end(); I != E; ++I) {
00687     const NamedDecl *Dec = I.getKey();
00688     unsigned i1 = I.getData();
00689     VarDefinition *VDef = &VarDefinitions[i1];
00690     assert(VDef->isReference());
00691 
00692     const unsigned *i2 = C2.lookup(Dec);
00693     if (!i2 || (*i2 != i1))
00694       VDef->Ref = 0;    // Mark this variable as undefined
00695   }
00696 }
00697 
00698 
00699 // Traverse the CFG in topological order, so all predecessors of a block
00700 // (excluding back-edges) are visited before the block itself.  At
00701 // each point in the code, we calculate a Context, which holds the set of
00702 // variable definitions which are visible at that point in execution.
00703 // Visible variables are mapped to their definitions using an array that
00704 // contains all definitions.
00705 //
00706 // At join points in the CFG, the set is computed as the intersection of
00707 // the incoming sets along each edge, E.g.
00708 //
00709 //                       { Context                 | VarDefinitions }
00710 //   int x = 0;          { x -> x1                 | x1 = 0 }
00711 //   int y = 0;          { x -> x1, y -> y1        | y1 = 0, x1 = 0 }
00712 //   if (b) x = 1;       { x -> x2, y -> y1        | x2 = 1, y1 = 0, ... }
00713 //   else   x = 2;       { x -> x3, y -> y1        | x3 = 2, x2 = 1, ... }
00714 //   ...                 { y -> y1  (x is unknown) | x3 = 2, x2 = 1, ... }
00715 //
00716 // This is essentially a simpler and more naive version of the standard SSA
00717 // algorithm.  Those definitions that remain in the intersection are from blocks
00718 // that strictly dominate the current block.  We do not bother to insert proper
00719 // phi nodes, because they are not used in our analysis; instead, wherever
00720 // a phi node would be required, we simply remove that definition from the
00721 // context (E.g. x above).
00722 //
00723 // The initial traversal does not capture back-edges, so those need to be
00724 // handled on a separate pass.  Whenever the first pass encounters an
00725 // incoming back edge, it duplicates the context, creating new definitions
00726 // that refer back to the originals.  (These correspond to places where SSA
00727 // might have to insert a phi node.)  On the second pass, these definitions are
00728 // set to NULL if the the variable has changed on the back-edge (i.e. a phi
00729 // node was actually required.)  E.g.
00730 //
00731 //                       { Context           | VarDefinitions }
00732 //   int x = 0, y = 0;   { x -> x1, y -> y1  | y1 = 0, x1 = 0 }
00733 //   while (b)           { x -> x2, y -> y1  | [1st:] x2=x1; [2nd:] x2=NULL; }
00734 //     x = x+1;          { x -> x3, y -> y1  | x3 = x2 + 1, ... }
00735 //   ...                 { y -> y1           | x3 = 2, x2 = 1, ... }
00736 //
00737 void LocalVariableMap::traverseCFG(CFG *CFGraph,
00738                                    PostOrderCFGView *SortedGraph,
00739                                    std::vector<CFGBlockInfo> &BlockInfo) {
00740   PostOrderCFGView::CFGBlockSet VisitedBlocks(CFGraph);
00741 
00742   CtxIndices.resize(CFGraph->getNumBlockIDs());
00743 
00744   for (PostOrderCFGView::iterator I = SortedGraph->begin(),
00745        E = SortedGraph->end(); I!= E; ++I) {
00746     const CFGBlock *CurrBlock = *I;
00747     int CurrBlockID = CurrBlock->getBlockID();
00748     CFGBlockInfo *CurrBlockInfo = &BlockInfo[CurrBlockID];
00749 
00750     VisitedBlocks.insert(CurrBlock);
00751 
00752     // Calculate the entry context for the current block
00753     bool HasBackEdges = false;
00754     bool CtxInit = true;
00755     for (CFGBlock::const_pred_iterator PI = CurrBlock->pred_begin(),
00756          PE  = CurrBlock->pred_end(); PI != PE; ++PI) {
00757       // if *PI -> CurrBlock is a back edge, so skip it
00758       if (*PI == 0 || !VisitedBlocks.alreadySet(*PI)) {
00759         HasBackEdges = true;
00760         continue;
00761       }
00762 
00763       int PrevBlockID = (*PI)->getBlockID();
00764       CFGBlockInfo *PrevBlockInfo = &BlockInfo[PrevBlockID];
00765 
00766       if (CtxInit) {
00767         CurrBlockInfo->EntryContext = PrevBlockInfo->ExitContext;
00768         CtxInit = false;
00769       }
00770       else {
00771         CurrBlockInfo->EntryContext =
00772           intersectContexts(CurrBlockInfo->EntryContext,
00773                             PrevBlockInfo->ExitContext);
00774       }
00775     }
00776 
00777     // Duplicate the context if we have back-edges, so we can call
00778     // intersectBackEdges later.
00779     if (HasBackEdges)
00780       CurrBlockInfo->EntryContext =
00781         createReferenceContext(CurrBlockInfo->EntryContext);
00782 
00783     // Create a starting context index for the current block
00784     saveContext(0, CurrBlockInfo->EntryContext);
00785     CurrBlockInfo->EntryIndex = getContextIndex();
00786 
00787     // Visit all the statements in the basic block.
00788     VarMapBuilder VMapBuilder(this, CurrBlockInfo->EntryContext);
00789     for (CFGBlock::const_iterator BI = CurrBlock->begin(),
00790          BE = CurrBlock->end(); BI != BE; ++BI) {
00791       switch (BI->getKind()) {
00792         case CFGElement::Statement: {
00793           const CFGStmt *CS = cast<CFGStmt>(&*BI);
00794           VMapBuilder.Visit(const_cast<Stmt*>(CS->getStmt()));
00795           break;
00796         }
00797         default:
00798           break;
00799       }
00800     }
00801     CurrBlockInfo->ExitContext = VMapBuilder.Ctx;
00802 
00803     // Mark variables on back edges as "unknown" if they've been changed.
00804     for (CFGBlock::const_succ_iterator SI = CurrBlock->succ_begin(),
00805          SE  = CurrBlock->succ_end(); SI != SE; ++SI) {
00806       // if CurrBlock -> *SI is *not* a back edge
00807       if (*SI == 0 || !VisitedBlocks.alreadySet(*SI))
00808         continue;
00809 
00810       CFGBlock *FirstLoopBlock = *SI;
00811       Context LoopBegin = BlockInfo[FirstLoopBlock->getBlockID()].EntryContext;
00812       Context LoopEnd   = CurrBlockInfo->ExitContext;
00813       intersectBackEdge(LoopBegin, LoopEnd);
00814     }
00815   }
00816 
00817   // Put an extra entry at the end of the indexed context array
00818   unsigned exitID = CFGraph->getExit().getBlockID();
00819   saveContext(0, BlockInfo[exitID].ExitContext);
00820 }
00821 
00822 /// Find the appropriate source locations to use when producing diagnostics for
00823 /// each block in the CFG.
00824 static void findBlockLocations(CFG *CFGraph,
00825                                PostOrderCFGView *SortedGraph,
00826                                std::vector<CFGBlockInfo> &BlockInfo) {
00827   for (PostOrderCFGView::iterator I = SortedGraph->begin(),
00828        E = SortedGraph->end(); I!= E; ++I) {
00829     const CFGBlock *CurrBlock = *I;
00830     CFGBlockInfo *CurrBlockInfo = &BlockInfo[CurrBlock->getBlockID()];
00831 
00832     // Find the source location of the last statement in the block, if the
00833     // block is not empty.
00834     if (const Stmt *S = CurrBlock->getTerminator()) {
00835       CurrBlockInfo->EntryLoc = CurrBlockInfo->ExitLoc = S->getLocStart();
00836     } else {
00837       for (CFGBlock::const_reverse_iterator BI = CurrBlock->rbegin(),
00838            BE = CurrBlock->rend(); BI != BE; ++BI) {
00839         // FIXME: Handle other CFGElement kinds.
00840         if (const CFGStmt *CS = dyn_cast<CFGStmt>(&*BI)) {
00841           CurrBlockInfo->ExitLoc = CS->getStmt()->getLocStart();
00842           break;
00843         }
00844       }
00845     }
00846 
00847     if (!CurrBlockInfo->ExitLoc.isInvalid()) {
00848       // This block contains at least one statement. Find the source location
00849       // of the first statement in the block.
00850       for (CFGBlock::const_iterator BI = CurrBlock->begin(),
00851            BE = CurrBlock->end(); BI != BE; ++BI) {
00852         // FIXME: Handle other CFGElement kinds.
00853         if (const CFGStmt *CS = dyn_cast<CFGStmt>(&*BI)) {
00854           CurrBlockInfo->EntryLoc = CS->getStmt()->getLocStart();
00855           break;
00856         }
00857       }
00858     } else if (CurrBlock->pred_size() == 1 && *CurrBlock->pred_begin() &&
00859                CurrBlock != &CFGraph->getExit()) {
00860       // The block is empty, and has a single predecessor. Use its exit
00861       // location.
00862       CurrBlockInfo->EntryLoc = CurrBlockInfo->ExitLoc =
00863           BlockInfo[(*CurrBlock->pred_begin())->getBlockID()].ExitLoc;
00864     }
00865   }
00866 }
00867 
00868 /// \brief Class which implements the core thread safety analysis routines.
00869 class ThreadSafetyAnalyzer {
00870   friend class BuildLockset;
00871 
00872   ThreadSafetyHandler       &Handler;
00873   Lockset::Factory          LocksetFactory;
00874   LocalVariableMap          LocalVarMap;
00875   std::vector<CFGBlockInfo> BlockInfo;
00876 
00877 public:
00878   ThreadSafetyAnalyzer(ThreadSafetyHandler &H) : Handler(H) {}
00879 
00880   Lockset addLock(const Lockset &LSet, const MutexID &Mutex,
00881                   const LockData &LDat);
00882   Lockset addLock(const Lockset &LSet, Expr *MutexExp, const NamedDecl *D,
00883                   const LockData &LDat);
00884   Lockset removeLock(const Lockset &LSet, const MutexID &Mutex,
00885                      SourceLocation UnlockLoc);
00886 
00887   template <class AttrType>
00888   Lockset addLocksToSet(const Lockset &LSet, LockKind LK, AttrType *Attr,
00889                         Expr *Exp, NamedDecl *D, VarDecl *VD = 0);
00890   Lockset removeLocksFromSet(const Lockset &LSet,
00891                              UnlockFunctionAttr *Attr,
00892                              Expr *Exp, NamedDecl* FunDecl);
00893 
00894   template <class AttrType>
00895   Lockset addTrylock(const Lockset &LSet,
00896                      LockKind LK, AttrType *Attr, Expr *Exp, NamedDecl *FunDecl,
00897                      const CFGBlock* PredBlock, const CFGBlock *CurrBlock,
00898                      Expr *BrE, bool Neg);
00899   const CallExpr* getTrylockCallExpr(const Stmt *Cond, LocalVarContext C,
00900                                      bool &Negate);
00901   Lockset handleTrylock(const Lockset &LSet,
00902                         const CFGBlock* PredBlock,
00903                         const CFGBlock *CurrBlock);
00904 
00905   Lockset intersectAndWarn(const CFGBlockInfo &Block1, CFGBlockSide Side1,
00906                            const CFGBlockInfo &Block2, CFGBlockSide Side2,
00907                            LockErrorKind LEK);
00908 
00909   void runAnalysis(AnalysisDeclContext &AC);
00910 };
00911 
00912 
00913 /// \brief Add a new lock to the lockset, warning if the lock is already there.
00914 /// \param Mutex -- the Mutex expression for the lock
00915 /// \param LDat  -- the LockData for the lock
00916 Lockset ThreadSafetyAnalyzer::addLock(const Lockset &LSet,
00917                                       const MutexID &Mutex,
00918                                       const LockData &LDat) {
00919   // FIXME: deal with acquired before/after annotations.
00920   // FIXME: Don't always warn when we have support for reentrant locks.
00921   if (LSet.lookup(Mutex)) {
00922     Handler.handleDoubleLock(Mutex.getName(), LDat.AcquireLoc);
00923     return LSet;
00924   } else {
00925     return LocksetFactory.add(LSet, Mutex, LDat);
00926   }
00927 }
00928 
00929 /// \brief Construct a new mutex and add it to the lockset.
00930 Lockset ThreadSafetyAnalyzer::addLock(const Lockset &LSet,
00931                                       Expr *MutexExp, const NamedDecl *D,
00932                                       const LockData &LDat) {
00933   MutexID Mutex(MutexExp, 0, D);
00934   if (!Mutex.isValid()) {
00935     MutexID::warnInvalidLock(Handler, MutexExp, 0, D);
00936     return LSet;
00937   }
00938   return addLock(LSet, Mutex, LDat);
00939 }
00940 
00941 
00942 /// \brief Remove a lock from the lockset, warning if the lock is not there.
00943 /// \param LockExp The lock expression corresponding to the lock to be removed
00944 /// \param UnlockLoc The source location of the unlock (only used in error msg)
00945 Lockset ThreadSafetyAnalyzer::removeLock(const Lockset &LSet,
00946                                          const MutexID &Mutex,
00947                                          SourceLocation UnlockLoc) {
00948   const LockData *LDat = LSet.lookup(Mutex);
00949   if (!LDat) {
00950     Handler.handleUnmatchedUnlock(Mutex.getName(), UnlockLoc);
00951     return LSet;
00952   }
00953   else {
00954     Lockset Result = LSet;
00955     // For scoped-lockable vars, remove the mutex associated with this var.
00956     if (LDat->UnderlyingMutex.isValid())
00957       Result = removeLock(Result, LDat->UnderlyingMutex, UnlockLoc);
00958     return LocksetFactory.remove(Result, Mutex);
00959   }
00960 }
00961 
00962 /// \brief This function, parameterized by an attribute type, is used to add a
00963 /// set of locks specified as attribute arguments to the lockset.
00964 template <typename AttrType>
00965 Lockset ThreadSafetyAnalyzer::addLocksToSet(const Lockset &LSet,
00966                                             LockKind LK, AttrType *Attr,
00967                                             Expr *Exp, NamedDecl* FunDecl,
00968                                             VarDecl *VD) {
00969   typedef typename AttrType::args_iterator iterator_type;
00970 
00971   SourceLocation ExpLocation = Exp->getExprLoc();
00972 
00973   // Figure out if we're calling the constructor of scoped lockable class
00974   bool isScopedVar = false;
00975   if (VD) {
00976     if (CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FunDecl)) {
00977       CXXRecordDecl* PD = CD->getParent();
00978       if (PD && PD->getAttr<ScopedLockableAttr>())
00979         isScopedVar = true;
00980     }
00981   }
00982 
00983   if (Attr->args_size() == 0) {
00984     // The mutex held is the "this" object.
00985     MutexID Mutex(0, Exp, FunDecl);
00986     if (!Mutex.isValid()) {
00987       MutexID::warnInvalidLock(Handler, 0, Exp, FunDecl);
00988       return LSet;
00989     }
00990     else {
00991       return addLock(LSet, Mutex, LockData(ExpLocation, LK));
00992     }
00993   }
00994 
00995   Lockset Result = LSet;
00996   for (iterator_type I=Attr->args_begin(), E=Attr->args_end(); I != E; ++I) {
00997     MutexID Mutex(*I, Exp, FunDecl);
00998     if (!Mutex.isValid())
00999       MutexID::warnInvalidLock(Handler, *I, Exp, FunDecl);
01000     else {
01001       Result = addLock(Result, Mutex, LockData(ExpLocation, LK));
01002       if (isScopedVar) {
01003         // For scoped lockable vars, map this var to its underlying mutex.
01004         DeclRefExpr DRE(VD, false, VD->getType(), VK_LValue, VD->getLocation());
01005         MutexID SMutex(&DRE, 0, 0);
01006         Result = addLock(Result, SMutex,
01007                          LockData(VD->getLocation(), LK, Mutex));
01008       }
01009     }
01010   }
01011   return Result;
01012 }
01013 
01014 /// \brief This function removes a set of locks specified as attribute
01015 /// arguments from the lockset.
01016 Lockset ThreadSafetyAnalyzer::removeLocksFromSet(const Lockset &LSet,
01017                                                  UnlockFunctionAttr *Attr,
01018                                                  Expr *Exp, NamedDecl* FunDecl) {
01019   SourceLocation ExpLocation;
01020   if (Exp) ExpLocation = Exp->getExprLoc();
01021 
01022   if (Attr->args_size() == 0) {
01023     // The mutex held is the "this" object.
01024     MutexID Mu(0, Exp, FunDecl);
01025     if (!Mu.isValid()) {
01026       MutexID::warnInvalidLock(Handler, 0, Exp, FunDecl);
01027       return LSet;
01028     } else {
01029       return removeLock(LSet, Mu, ExpLocation);
01030     }
01031   }
01032 
01033   Lockset Result = LSet;
01034   for (UnlockFunctionAttr::args_iterator I = Attr->args_begin(),
01035        E = Attr->args_end(); I != E; ++I) {
01036     MutexID Mutex(*I, Exp, FunDecl);
01037     if (!Mutex.isValid())
01038       MutexID::warnInvalidLock(Handler, *I, Exp, FunDecl);
01039     else
01040       Result = removeLock(Result, Mutex, ExpLocation);
01041   }
01042   return Result;
01043 }
01044 
01045 
01046 /// \brief Add lock to set, if the current block is in the taken branch of a
01047 /// trylock.
01048 template <class AttrType>
01049 Lockset ThreadSafetyAnalyzer::addTrylock(const Lockset &LSet,
01050                                          LockKind LK, AttrType *Attr,
01051                                          Expr *Exp, NamedDecl *FunDecl,
01052                                          const CFGBlock *PredBlock,
01053                                          const CFGBlock *CurrBlock,
01054                                          Expr *BrE, bool Neg) {
01055   // Find out which branch has the lock
01056   bool branch = 0;
01057   if (CXXBoolLiteralExpr *BLE = dyn_cast_or_null<CXXBoolLiteralExpr>(BrE)) {
01058     branch = BLE->getValue();
01059   }
01060   else if (IntegerLiteral *ILE = dyn_cast_or_null<IntegerLiteral>(BrE)) {
01061     branch = ILE->getValue().getBoolValue();
01062   }
01063   int branchnum = branch ? 0 : 1;
01064   if (Neg) branchnum = !branchnum;
01065 
01066   Lockset Result = LSet;
01067   // If we've taken the trylock branch, then add the lock
01068   int i = 0;
01069   for (CFGBlock::const_succ_iterator SI = PredBlock->succ_begin(),
01070        SE = PredBlock->succ_end(); SI != SE && i < 2; ++SI, ++i) {
01071     if (*SI == CurrBlock && i == branchnum) {
01072       Result = addLocksToSet(Result, LK, Attr, Exp, FunDecl, 0);
01073     }
01074   }
01075   return Result;
01076 }
01077 
01078 
01079 // If Cond can be traced back to a function call, return the call expression.
01080 // The negate variable should be called with false, and will be set to true
01081 // if the function call is negated, e.g. if (!mu.tryLock(...))
01082 const CallExpr* ThreadSafetyAnalyzer::getTrylockCallExpr(const Stmt *Cond,
01083                                                          LocalVarContext C,
01084                                                          bool &Negate) {
01085   if (!Cond)
01086     return 0;
01087 
01088   if (const CallExpr *CallExp = dyn_cast<CallExpr>(Cond)) {
01089     return CallExp;
01090   }
01091   else if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(Cond)) {
01092     return getTrylockCallExpr(CE->getSubExpr(), C, Negate);
01093   }
01094   else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Cond)) {
01095     const Expr *E = LocalVarMap.lookupExpr(DRE->getDecl(), C);
01096     return getTrylockCallExpr(E, C, Negate);
01097   }
01098   else if (const UnaryOperator *UOP = dyn_cast<UnaryOperator>(Cond)) {
01099     if (UOP->getOpcode() == UO_LNot) {
01100       Negate = !Negate;
01101       return getTrylockCallExpr(UOP->getSubExpr(), C, Negate);
01102     }
01103   }
01104   // FIXME -- handle && and || as well.
01105   return NULL;
01106 }
01107 
01108 
01109 /// \brief Process a conditional branch from a previous block to the current
01110 /// block, looking for trylock calls.
01111 Lockset ThreadSafetyAnalyzer::handleTrylock(const Lockset &LSet,
01112                                             const CFGBlock *PredBlock,
01113                                             const CFGBlock *CurrBlock) {
01114   bool Negate = false;
01115   const Stmt *Cond = PredBlock->getTerminatorCondition();
01116   const CFGBlockInfo *PredBlockInfo = &BlockInfo[PredBlock->getBlockID()];
01117   const LocalVarContext &LVarCtx = PredBlockInfo->ExitContext;
01118 
01119   CallExpr *Exp = const_cast<CallExpr*>(
01120     getTrylockCallExpr(Cond, LVarCtx, Negate));
01121   if (!Exp)
01122     return LSet;
01123 
01124   NamedDecl *FunDecl = dyn_cast_or_null<NamedDecl>(Exp->getCalleeDecl());
01125   if(!FunDecl || !FunDecl->hasAttrs())
01126     return LSet;
01127 
01128   Lockset Result = LSet;
01129 
01130   // If the condition is a call to a Trylock function, then grab the attributes
01131   AttrVec &ArgAttrs = FunDecl->getAttrs();
01132   for (unsigned i = 0; i < ArgAttrs.size(); ++i) {
01133     Attr *Attr = ArgAttrs[i];
01134     switch (Attr->getKind()) {
01135       case attr::ExclusiveTrylockFunction: {
01136         ExclusiveTrylockFunctionAttr *A =
01137           cast<ExclusiveTrylockFunctionAttr>(Attr);
01138         Result = addTrylock(Result, LK_Exclusive, A, Exp, FunDecl,
01139                             PredBlock, CurrBlock,
01140                             A->getSuccessValue(), Negate);
01141         break;
01142       }
01143       case attr::SharedTrylockFunction: {
01144         SharedTrylockFunctionAttr *A =
01145           cast<SharedTrylockFunctionAttr>(Attr);
01146         Result = addTrylock(Result, LK_Shared, A, Exp, FunDecl,
01147                             PredBlock, CurrBlock,
01148                             A->getSuccessValue(), Negate);
01149         break;
01150       }
01151       default:
01152         break;
01153     }
01154   }
01155   return Result;
01156 }
01157 
01158 
01159 /// \brief We use this class to visit different types of expressions in
01160 /// CFGBlocks, and build up the lockset.
01161 /// An expression may cause us to add or remove locks from the lockset, or else
01162 /// output error messages related to missing locks.
01163 /// FIXME: In future, we may be able to not inherit from a visitor.
01164 class BuildLockset : public StmtVisitor<BuildLockset> {
01165   friend class ThreadSafetyAnalyzer;
01166 
01167   ThreadSafetyAnalyzer *Analyzer;
01168   Lockset LSet;
01169   LocalVariableMap::Context LVarCtx;
01170   unsigned CtxIndex;
01171 
01172   // Helper functions
01173   const ValueDecl *getValueDecl(Expr *Exp);
01174 
01175   void warnIfMutexNotHeld(const NamedDecl *D, Expr *Exp, AccessKind AK,
01176                           Expr *MutexExp, ProtectedOperationKind POK);
01177 
01178   void checkAccess(Expr *Exp, AccessKind AK);
01179   void checkDereference(Expr *Exp, AccessKind AK);
01180   void handleCall(Expr *Exp, NamedDecl *D, VarDecl *VD = 0);
01181 
01182   /// \brief Returns true if the lockset contains a lock, regardless of whether
01183   /// the lock is held exclusively or shared.
01184   bool locksetContains(const MutexID &Lock) const {
01185     return LSet.lookup(Lock);
01186   }
01187 
01188   /// \brief Returns true if the lockset contains a lock with the passed in
01189   /// locktype.
01190   bool locksetContains(const MutexID &Lock, LockKind KindRequested) const {
01191     const LockData *LockHeld = LSet.lookup(Lock);
01192     return (LockHeld && KindRequested == LockHeld->LKind);
01193   }
01194 
01195   /// \brief Returns true if the lockset contains a lock with at least the
01196   /// passed in locktype. So for example, if we pass in LK_Shared, this function
01197   /// returns true if the lock is held LK_Shared or LK_Exclusive. If we pass in
01198   /// LK_Exclusive, this function returns true if the lock is held LK_Exclusive.
01199   bool locksetContainsAtLeast(const MutexID &Lock,
01200                               LockKind KindRequested) const {
01201     switch (KindRequested) {
01202       case LK_Shared:
01203         return locksetContains(Lock);
01204       case LK_Exclusive:
01205         return locksetContains(Lock, KindRequested);
01206     }
01207     llvm_unreachable("Unknown LockKind");
01208   }
01209 
01210 public:
01211   BuildLockset(ThreadSafetyAnalyzer *Anlzr, CFGBlockInfo &Info)
01212     : StmtVisitor<BuildLockset>(),
01213       Analyzer(Anlzr),
01214       LSet(Info.EntrySet),
01215       LVarCtx(Info.EntryContext),
01216       CtxIndex(Info.EntryIndex)
01217   {}
01218 
01219   void VisitUnaryOperator(UnaryOperator *UO);
01220   void VisitBinaryOperator(BinaryOperator *BO);
01221   void VisitCastExpr(CastExpr *CE);
01222   void VisitCallExpr(CallExpr *Exp);
01223   void VisitCXXConstructExpr(CXXConstructExpr *Exp);
01224   void VisitDeclStmt(DeclStmt *S);
01225 };
01226 
01227 
01228 /// \brief Gets the value decl pointer from DeclRefExprs or MemberExprs
01229 const ValueDecl *BuildLockset::getValueDecl(Expr *Exp) {
01230   if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Exp))
01231     return DR->getDecl();
01232 
01233   if (const MemberExpr *ME = dyn_cast<MemberExpr>(Exp))
01234     return ME->getMemberDecl();
01235 
01236   return 0;
01237 }
01238 
01239 /// \brief Warn if the LSet does not contain a lock sufficient to protect access
01240 /// of at least the passed in AccessKind.
01241 void BuildLockset::warnIfMutexNotHeld(const NamedDecl *D, Expr *Exp,
01242                                       AccessKind AK, Expr *MutexExp,
01243                                       ProtectedOperationKind POK) {
01244   LockKind LK = getLockKindFromAccessKind(AK);
01245 
01246   MutexID Mutex(MutexExp, Exp, D);
01247   if (!Mutex.isValid())
01248     MutexID::warnInvalidLock(Analyzer->Handler, MutexExp, Exp, D);
01249   else if (!locksetContainsAtLeast(Mutex, LK))
01250     Analyzer->Handler.handleMutexNotHeld(D, POK, Mutex.getName(), LK,
01251                                          Exp->getExprLoc());
01252 }
01253 
01254 /// \brief This method identifies variable dereferences and checks pt_guarded_by
01255 /// and pt_guarded_var annotations. Note that we only check these annotations
01256 /// at the time a pointer is dereferenced.
01257 /// FIXME: We need to check for other types of pointer dereferences
01258 /// (e.g. [], ->) and deal with them here.
01259 /// \param Exp An expression that has been read or written.
01260 void BuildLockset::checkDereference(Expr *Exp, AccessKind AK) {
01261   UnaryOperator *UO = dyn_cast<UnaryOperator>(Exp);
01262   if (!UO || UO->getOpcode() != clang::UO_Deref)
01263     return;
01264   Exp = UO->getSubExpr()->IgnoreParenCasts();
01265 
01266   const ValueDecl *D = getValueDecl(Exp);
01267   if(!D || !D->hasAttrs())
01268     return;
01269 
01270   if (D->getAttr<PtGuardedVarAttr>() && LSet.isEmpty())
01271     Analyzer->Handler.handleNoMutexHeld(D, POK_VarDereference, AK,
01272                                         Exp->getExprLoc());
01273 
01274   const AttrVec &ArgAttrs = D->getAttrs();
01275   for(unsigned i = 0, Size = ArgAttrs.size(); i < Size; ++i)
01276     if (PtGuardedByAttr *PGBAttr = dyn_cast<PtGuardedByAttr>(ArgAttrs[i]))
01277       warnIfMutexNotHeld(D, Exp, AK, PGBAttr->getArg(), POK_VarDereference);
01278 }
01279 
01280 /// \brief Checks guarded_by and guarded_var attributes.
01281 /// Whenever we identify an access (read or write) of a DeclRefExpr or
01282 /// MemberExpr, we need to check whether there are any guarded_by or
01283 /// guarded_var attributes, and make sure we hold the appropriate mutexes.
01284 void BuildLockset::checkAccess(Expr *Exp, AccessKind AK) {
01285   const ValueDecl *D = getValueDecl(Exp);
01286   if(!D || !D->hasAttrs())
01287     return;
01288 
01289   if (D->getAttr<GuardedVarAttr>() && LSet.isEmpty())
01290     Analyzer->Handler.handleNoMutexHeld(D, POK_VarAccess, AK,
01291                                         Exp->getExprLoc());
01292 
01293   const AttrVec &ArgAttrs = D->getAttrs();
01294   for(unsigned i = 0, Size = ArgAttrs.size(); i < Size; ++i)
01295     if (GuardedByAttr *GBAttr = dyn_cast<GuardedByAttr>(ArgAttrs[i]))
01296       warnIfMutexNotHeld(D, Exp, AK, GBAttr->getArg(), POK_VarAccess);
01297 }
01298 
01299 /// \brief Process a function call, method call, constructor call,
01300 /// or destructor call.  This involves looking at the attributes on the
01301 /// corresponding function/method/constructor/destructor, issuing warnings,
01302 /// and updating the locksets accordingly.
01303 ///
01304 /// FIXME: For classes annotated with one of the guarded annotations, we need
01305 /// to treat const method calls as reads and non-const method calls as writes,
01306 /// and check that the appropriate locks are held. Non-const method calls with
01307 /// the same signature as const method calls can be also treated as reads.
01308 ///
01309 /// FIXME: We need to also visit CallExprs to catch/check global functions.
01310 ///
01311 /// FIXME: Do not flag an error for member variables accessed in constructors/
01312 /// destructors
01313 void BuildLockset::handleCall(Expr *Exp, NamedDecl *D, VarDecl *VD) {
01314   AttrVec &ArgAttrs = D->getAttrs();
01315   for(unsigned i = 0; i < ArgAttrs.size(); ++i) {
01316     Attr *Attr = ArgAttrs[i];
01317     switch (Attr->getKind()) {
01318       // When we encounter an exclusive lock function, we need to add the lock
01319       // to our lockset with kind exclusive.
01320       case attr::ExclusiveLockFunction: {
01321         ExclusiveLockFunctionAttr *A = cast<ExclusiveLockFunctionAttr>(Attr);
01322         LSet = Analyzer->addLocksToSet(LSet, LK_Exclusive, A, Exp, D, VD);
01323         break;
01324       }
01325 
01326       // When we encounter a shared lock function, we need to add the lock
01327       // to our lockset with kind shared.
01328       case attr::SharedLockFunction: {
01329         SharedLockFunctionAttr *A = cast<SharedLockFunctionAttr>(Attr);
01330         LSet = Analyzer->addLocksToSet(LSet, LK_Shared, A, Exp, D, VD);
01331         break;
01332       }
01333 
01334       // When we encounter an unlock function, we need to remove unlocked
01335       // mutexes from the lockset, and flag a warning if they are not there.
01336       case attr::UnlockFunction: {
01337         UnlockFunctionAttr *UFAttr = cast<UnlockFunctionAttr>(Attr);
01338         LSet = Analyzer->removeLocksFromSet(LSet, UFAttr, Exp, D);
01339         break;
01340       }
01341 
01342       case attr::ExclusiveLocksRequired: {
01343         ExclusiveLocksRequiredAttr *ELRAttr =
01344             cast<ExclusiveLocksRequiredAttr>(Attr);
01345 
01346         for (ExclusiveLocksRequiredAttr::args_iterator
01347              I = ELRAttr->args_begin(), E = ELRAttr->args_end(); I != E; ++I)
01348           warnIfMutexNotHeld(D, Exp, AK_Written, *I, POK_FunctionCall);
01349         break;
01350       }
01351 
01352       case attr::SharedLocksRequired: {
01353         SharedLocksRequiredAttr *SLRAttr = cast<SharedLocksRequiredAttr>(Attr);
01354 
01355         for (SharedLocksRequiredAttr::args_iterator I = SLRAttr->args_begin(),
01356              E = SLRAttr->args_end(); I != E; ++I)
01357           warnIfMutexNotHeld(D, Exp, AK_Read, *I, POK_FunctionCall);
01358         break;
01359       }
01360 
01361       case attr::LocksExcluded: {
01362         LocksExcludedAttr *LEAttr = cast<LocksExcludedAttr>(Attr);
01363         for (LocksExcludedAttr::args_iterator I = LEAttr->args_begin(),
01364             E = LEAttr->args_end(); I != E; ++I) {
01365           MutexID Mutex(*I, Exp, D);
01366           if (!Mutex.isValid())
01367             MutexID::warnInvalidLock(Analyzer->Handler, *I, Exp, D);
01368           else if (locksetContains(Mutex))
01369             Analyzer->Handler.handleFunExcludesLock(D->getName(),
01370                                                     Mutex.getName(),
01371                                                     Exp->getExprLoc());
01372         }
01373         break;
01374       }
01375 
01376       // Ignore other (non thread-safety) attributes
01377       default:
01378         break;
01379     }
01380   }
01381 }
01382 
01383 
01384 /// \brief For unary operations which read and write a variable, we need to
01385 /// check whether we hold any required mutexes. Reads are checked in
01386 /// VisitCastExpr.
01387 void BuildLockset::VisitUnaryOperator(UnaryOperator *UO) {
01388   switch (UO->getOpcode()) {
01389     case clang::UO_PostDec:
01390     case clang::UO_PostInc:
01391     case clang::UO_PreDec:
01392     case clang::UO_PreInc: {
01393       Expr *SubExp = UO->getSubExpr()->IgnoreParenCasts();
01394       checkAccess(SubExp, AK_Written);
01395       checkDereference(SubExp, AK_Written);
01396       break;
01397     }
01398     default:
01399       break;
01400   }
01401 }
01402 
01403 /// For binary operations which assign to a variable (writes), we need to check
01404 /// whether we hold any required mutexes.
01405 /// FIXME: Deal with non-primitive types.
01406 void BuildLockset::VisitBinaryOperator(BinaryOperator *BO) {
01407   if (!BO->isAssignmentOp())
01408     return;
01409 
01410   // adjust the context
01411   LVarCtx = Analyzer->LocalVarMap.getNextContext(CtxIndex, BO, LVarCtx);
01412 
01413   Expr *LHSExp = BO->getLHS()->IgnoreParenCasts();
01414   checkAccess(LHSExp, AK_Written);
01415   checkDereference(LHSExp, AK_Written);
01416 }
01417 
01418 /// Whenever we do an LValue to Rvalue cast, we are reading a variable and
01419 /// need to ensure we hold any required mutexes.
01420 /// FIXME: Deal with non-primitive types.
01421 void BuildLockset::VisitCastExpr(CastExpr *CE) {
01422   if (CE->getCastKind() != CK_LValueToRValue)
01423     return;
01424   Expr *SubExp = CE->getSubExpr()->IgnoreParenCasts();
01425   checkAccess(SubExp, AK_Read);
01426   checkDereference(SubExp, AK_Read);
01427 }
01428 
01429 
01430 void BuildLockset::VisitCallExpr(CallExpr *Exp) {
01431   NamedDecl *D = dyn_cast_or_null<NamedDecl>(Exp->getCalleeDecl());
01432   if(!D || !D->hasAttrs())
01433     return;
01434   handleCall(Exp, D);
01435 }
01436 
01437 void BuildLockset::VisitCXXConstructExpr(CXXConstructExpr *Exp) {
01438   // FIXME -- only handles constructors in DeclStmt below.
01439 }
01440 
01441 void BuildLockset::VisitDeclStmt(DeclStmt *S) {
01442   // adjust the context
01443   LVarCtx = Analyzer->LocalVarMap.getNextContext(CtxIndex, S, LVarCtx);
01444 
01445   DeclGroupRef DGrp = S->getDeclGroup();
01446   for (DeclGroupRef::iterator I = DGrp.begin(), E = DGrp.end(); I != E; ++I) {
01447     Decl *D = *I;
01448     if (VarDecl *VD = dyn_cast_or_null<VarDecl>(D)) {
01449       Expr *E = VD->getInit();
01450       if (CXXConstructExpr *CE = dyn_cast_or_null<CXXConstructExpr>(E)) {
01451         NamedDecl *CtorD = dyn_cast_or_null<NamedDecl>(CE->getConstructor());
01452         if (!CtorD || !CtorD->hasAttrs())
01453           return;
01454         handleCall(CE, CtorD, VD);
01455       }
01456     }
01457   }
01458 }
01459 
01460 
01461 /// \brief Compute the intersection of two locksets and issue warnings for any
01462 /// locks in the symmetric difference.
01463 ///
01464 /// This function is used at a merge point in the CFG when comparing the lockset
01465 /// of each branch being merged. For example, given the following sequence:
01466 /// A; if () then B; else C; D; we need to check that the lockset after B and C
01467 /// are the same. In the event of a difference, we use the intersection of these
01468 /// two locksets at the start of D.
01469 Lockset ThreadSafetyAnalyzer::intersectAndWarn(const CFGBlockInfo &Block1,
01470                                                CFGBlockSide Side1,
01471                                                const CFGBlockInfo &Block2,
01472                                                CFGBlockSide Side2,
01473                                                LockErrorKind LEK) {
01474   Lockset LSet1 = Block1.getSet(Side1);
01475   Lockset LSet2 = Block2.getSet(Side2);
01476 
01477   Lockset Intersection = LSet1;
01478   for (Lockset::iterator I = LSet2.begin(), E = LSet2.end(); I != E; ++I) {
01479     const MutexID &LSet2Mutex = I.getKey();
01480     const LockData &LSet2LockData = I.getData();
01481     if (const LockData *LD = LSet1.lookup(LSet2Mutex)) {
01482       if (LD->LKind != LSet2LockData.LKind) {
01483         Handler.handleExclusiveAndShared(LSet2Mutex.getName(),
01484                                          LSet2LockData.AcquireLoc,
01485                                          LD->AcquireLoc);
01486         if (LD->LKind != LK_Exclusive)
01487           Intersection = LocksetFactory.add(Intersection, LSet2Mutex,
01488                                             LSet2LockData);
01489       }
01490     } else {
01491       Handler.handleMutexHeldEndOfScope(LSet2Mutex.getName(),
01492                                         LSet2LockData.AcquireLoc,
01493                                         Block1.getLocation(Side1), LEK);
01494     }
01495   }
01496 
01497   for (Lockset::iterator I = LSet1.begin(), E = LSet1.end(); I != E; ++I) {
01498     if (!LSet2.contains(I.getKey())) {
01499       const MutexID &Mutex = I.getKey();
01500       const LockData &MissingLock = I.getData();
01501       Handler.handleMutexHeldEndOfScope(Mutex.getName(),
01502                                         MissingLock.AcquireLoc,
01503                                         Block2.getLocation(Side2), LEK);
01504       Intersection = LocksetFactory.remove(Intersection, Mutex);
01505     }
01506   }
01507   return Intersection;
01508 }
01509 
01510 
01511 /// \brief Check a function's CFG for thread-safety violations.
01512 ///
01513 /// We traverse the blocks in the CFG, compute the set of mutexes that are held
01514 /// at the end of each block, and issue warnings for thread safety violations.
01515 /// Each block in the CFG is traversed exactly once.
01516 void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) {
01517   CFG *CFGraph = AC.getCFG();
01518   if (!CFGraph) return;
01519   const NamedDecl *D = dyn_cast_or_null<NamedDecl>(AC.getDecl());
01520 
01521   if (!D)
01522     return;  // Ignore anonymous functions for now.
01523   if (D->getAttr<NoThreadSafetyAnalysisAttr>())
01524     return;
01525   // FIXME: Do something a bit more intelligent inside constructor and
01526   // destructor code.  Constructors and destructors must assume unique access
01527   // to 'this', so checks on member variable access is disabled, but we should
01528   // still enable checks on other objects.
01529   if (isa<CXXConstructorDecl>(D))
01530     return;  // Don't check inside constructors.
01531   if (isa<CXXDestructorDecl>(D))
01532     return;  // Don't check inside destructors.
01533 
01534   BlockInfo.resize(CFGraph->getNumBlockIDs(),
01535     CFGBlockInfo::getEmptyBlockInfo(LocksetFactory, LocalVarMap));
01536 
01537   // We need to explore the CFG via a "topological" ordering.
01538   // That way, we will be guaranteed to have information about required
01539   // predecessor locksets when exploring a new block.
01540   PostOrderCFGView *SortedGraph = AC.getAnalysis<PostOrderCFGView>();
01541   PostOrderCFGView::CFGBlockSet VisitedBlocks(CFGraph);
01542 
01543   // Compute SSA names for local variables
01544   LocalVarMap.traverseCFG(CFGraph, SortedGraph, BlockInfo);
01545 
01546   // Fill in source locations for all CFGBlocks.
01547   findBlockLocations(CFGraph, SortedGraph, BlockInfo);
01548 
01549   // Add locks from exclusive_locks_required and shared_locks_required
01550   // to initial lockset. Also turn off checking for lock and unlock functions.
01551   // FIXME: is there a more intelligent way to check lock/unlock functions?
01552   if (!SortedGraph->empty() && D->hasAttrs()) {
01553     const CFGBlock *FirstBlock = *SortedGraph->begin();
01554     Lockset &InitialLockset = BlockInfo[FirstBlock->getBlockID()].EntrySet;
01555     const AttrVec &ArgAttrs = D->getAttrs();
01556     for (unsigned i = 0; i < ArgAttrs.size(); ++i) {
01557       Attr *Attr = ArgAttrs[i];
01558       SourceLocation AttrLoc = Attr->getLocation();
01559       if (SharedLocksRequiredAttr *SLRAttr
01560             = dyn_cast<SharedLocksRequiredAttr>(Attr)) {
01561         for (SharedLocksRequiredAttr::args_iterator
01562              SLRIter = SLRAttr->args_begin(),
01563              SLREnd = SLRAttr->args_end(); SLRIter != SLREnd; ++SLRIter)
01564           InitialLockset = addLock(InitialLockset, *SLRIter, D,
01565                                    LockData(AttrLoc, LK_Shared));
01566       } else if (ExclusiveLocksRequiredAttr *ELRAttr
01567                    = dyn_cast<ExclusiveLocksRequiredAttr>(Attr)) {
01568         for (ExclusiveLocksRequiredAttr::args_iterator
01569              ELRIter = ELRAttr->args_begin(),
01570              ELREnd = ELRAttr->args_end(); ELRIter != ELREnd; ++ELRIter)
01571           InitialLockset = addLock(InitialLockset, *ELRIter, D,
01572                                    LockData(AttrLoc, LK_Exclusive));
01573       } else if (isa<UnlockFunctionAttr>(Attr)) {
01574         // Don't try to check unlock functions for now
01575         return;
01576       } else if (isa<ExclusiveLockFunctionAttr>(Attr)) {
01577         // Don't try to check lock functions for now
01578         return;
01579       } else if (isa<SharedLockFunctionAttr>(Attr)) {
01580         // Don't try to check lock functions for now
01581         return;
01582       }
01583     }
01584   }
01585 
01586   for (PostOrderCFGView::iterator I = SortedGraph->begin(),
01587        E = SortedGraph->end(); I!= E; ++I) {
01588     const CFGBlock *CurrBlock = *I;
01589     int CurrBlockID = CurrBlock->getBlockID();
01590     CFGBlockInfo *CurrBlockInfo = &BlockInfo[CurrBlockID];
01591 
01592     // Use the default initial lockset in case there are no predecessors.
01593     VisitedBlocks.insert(CurrBlock);
01594 
01595     // Iterate through the predecessor blocks and warn if the lockset for all
01596     // predecessors is not the same. We take the entry lockset of the current
01597     // block to be the intersection of all previous locksets.
01598     // FIXME: By keeping the intersection, we may output more errors in future
01599     // for a lock which is not in the intersection, but was in the union. We
01600     // may want to also keep the union in future. As an example, let's say
01601     // the intersection contains Mutex L, and the union contains L and M.
01602     // Later we unlock M. At this point, we would output an error because we
01603     // never locked M; although the real error is probably that we forgot to
01604     // lock M on all code paths. Conversely, let's say that later we lock M.
01605     // In this case, we should compare against the intersection instead of the
01606     // union because the real error is probably that we forgot to unlock M on
01607     // all code paths.
01608     bool LocksetInitialized = false;
01609     llvm::SmallVector<CFGBlock*, 8> SpecialBlocks;
01610     for (CFGBlock::const_pred_iterator PI = CurrBlock->pred_begin(),
01611          PE  = CurrBlock->pred_end(); PI != PE; ++PI) {
01612 
01613       // if *PI -> CurrBlock is a back edge
01614       if (*PI == 0 || !VisitedBlocks.alreadySet(*PI))
01615         continue;
01616 
01617       // Ignore edges from blocks that can't return.
01618       if ((*PI)->hasNoReturnElement())
01619         continue;
01620 
01621       // If the previous block ended in a 'continue' or 'break' statement, then
01622       // a difference in locksets is probably due to a bug in that block, rather
01623       // than in some other predecessor. In that case, keep the other
01624       // predecessor's lockset.
01625       if (const Stmt *Terminator = (*PI)->getTerminator()) {
01626         if (isa<ContinueStmt>(Terminator) || isa<BreakStmt>(Terminator)) {
01627           SpecialBlocks.push_back(*PI);
01628           continue;
01629         }
01630       }
01631 
01632       int PrevBlockID = (*PI)->getBlockID();
01633       CFGBlockInfo *PrevBlockInfo = &BlockInfo[PrevBlockID];
01634 
01635       if (!LocksetInitialized) {
01636         CurrBlockInfo->EntrySet = PrevBlockInfo->ExitSet;
01637         LocksetInitialized = true;
01638       } else {
01639         CurrBlockInfo->EntrySet =
01640           intersectAndWarn(*CurrBlockInfo, CBS_Entry,
01641                            *PrevBlockInfo, CBS_Exit,
01642                            LEK_LockedSomePredecessors);
01643       }
01644     }
01645 
01646     // Process continue and break blocks. Assume that the lockset for the
01647     // resulting block is unaffected by any discrepancies in them.
01648     for (unsigned SpecialI = 0, SpecialN = SpecialBlocks.size();
01649          SpecialI < SpecialN; ++SpecialI) {
01650       CFGBlock *PrevBlock = SpecialBlocks[SpecialI];
01651       int PrevBlockID = PrevBlock->getBlockID();
01652       CFGBlockInfo *PrevBlockInfo = &BlockInfo[PrevBlockID];
01653 
01654       if (!LocksetInitialized) {
01655         CurrBlockInfo->EntrySet = PrevBlockInfo->ExitSet;
01656         LocksetInitialized = true;
01657       } else {
01658         // Determine whether this edge is a loop terminator for diagnostic
01659         // purposes. FIXME: A 'break' statement might be a loop terminator, but
01660         // it might also be part of a switch. Also, a subsequent destructor
01661         // might add to the lockset, in which case the real issue might be a
01662         // double lock on the other path.
01663         const Stmt *Terminator = PrevBlock->getTerminator();
01664         bool IsLoop = Terminator && isa<ContinueStmt>(Terminator);
01665 
01666         // Do not update EntrySet.
01667         intersectAndWarn(*CurrBlockInfo, CBS_Entry, *PrevBlockInfo, CBS_Exit,
01668                          IsLoop ? LEK_LockedSomeLoopIterations
01669                                 : LEK_LockedSomePredecessors);
01670       }
01671     }
01672 
01673     // If the previous block ended in a trylock, then grab any extra mutexes
01674     // from the trylock.
01675     for (CFGBlock::const_pred_iterator PI = CurrBlock->pred_begin(),
01676          PE = CurrBlock->pred_end(); PI != PE; ++PI) {
01677       // If the predecessor ended in a branch, then process any trylocks.
01678       if ((*PI)->getTerminatorCondition()) {
01679         CurrBlockInfo->EntrySet = handleTrylock(CurrBlockInfo->EntrySet,
01680                                                 *PI, CurrBlock);
01681       }
01682     }
01683 
01684     BuildLockset LocksetBuilder(this, *CurrBlockInfo);
01685 
01686     // Visit all the statements in the basic block.
01687     for (CFGBlock::const_iterator BI = CurrBlock->begin(),
01688          BE = CurrBlock->end(); BI != BE; ++BI) {
01689       switch (BI->getKind()) {
01690         case CFGElement::Statement: {
01691           const CFGStmt *CS = cast<CFGStmt>(&*BI);
01692           LocksetBuilder.Visit(const_cast<Stmt*>(CS->getStmt()));
01693           break;
01694         }
01695         // Ignore BaseDtor, MemberDtor, and TemporaryDtor for now.
01696         case CFGElement::AutomaticObjectDtor: {
01697           const CFGAutomaticObjDtor *AD = cast<CFGAutomaticObjDtor>(&*BI);
01698           CXXDestructorDecl *DD = const_cast<CXXDestructorDecl*>(
01699             AD->getDestructorDecl(AC.getASTContext()));
01700           if (!DD->hasAttrs())
01701             break;
01702 
01703           // Create a dummy expression,
01704           VarDecl *VD = const_cast<VarDecl*>(AD->getVarDecl());
01705           DeclRefExpr DRE(VD, false, VD->getType(), VK_LValue,
01706                           AD->getTriggerStmt()->getLocEnd());
01707           LocksetBuilder.handleCall(&DRE, DD);
01708           break;
01709         }
01710         default:
01711           break;
01712       }
01713     }
01714     CurrBlockInfo->ExitSet = LocksetBuilder.LSet;
01715 
01716     // For every back edge from CurrBlock (the end of the loop) to another block
01717     // (FirstLoopBlock) we need to check that the Lockset of Block is equal to
01718     // the one held at the beginning of FirstLoopBlock. We can look up the
01719     // Lockset held at the beginning of FirstLoopBlock in the EntryLockSets map.
01720     for (CFGBlock::const_succ_iterator SI = CurrBlock->succ_begin(),
01721          SE  = CurrBlock->succ_end(); SI != SE; ++SI) {
01722 
01723       // if CurrBlock -> *SI is *not* a back edge
01724       if (*SI == 0 || !VisitedBlocks.alreadySet(*SI))
01725         continue;
01726 
01727       CFGBlock *FirstLoopBlock = *SI;
01728       CFGBlockInfo &PreLoop = BlockInfo[FirstLoopBlock->getBlockID()];
01729       CFGBlockInfo &LoopEnd = BlockInfo[CurrBlockID];
01730       intersectAndWarn(LoopEnd, CBS_Exit, PreLoop, CBS_Entry,
01731                        LEK_LockedSomeLoopIterations);
01732     }
01733   }
01734 
01735   CFGBlockInfo &Initial = BlockInfo[CFGraph->getEntry().getBlockID()];
01736   CFGBlockInfo &Final = BlockInfo[CFGraph->getExit().getBlockID()];
01737 
01738   // FIXME: Should we call this function for all blocks which exit the function?
01739   intersectAndWarn(Initial, CBS_Entry, Final, CBS_Exit,
01740                    LEK_LockedAtEndOfFunction);
01741 }
01742 
01743 } // end anonymous namespace
01744 
01745 
01746 namespace clang {
01747 namespace thread_safety {
01748 
01749 /// \brief Check a function's CFG for thread-safety violations.
01750 ///
01751 /// We traverse the blocks in the CFG, compute the set of mutexes that are held
01752 /// at the end of each block, and issue warnings for thread safety violations.
01753 /// Each block in the CFG is traversed exactly once.
01754 void runThreadSafetyAnalysis(AnalysisDeclContext &AC,
01755                              ThreadSafetyHandler &Handler) {
01756   ThreadSafetyAnalyzer Analyzer(Handler);
01757   Analyzer.runAnalysis(AC);
01758 }
01759 
01760 /// \brief Helper function that returns a LockKind required for the given level
01761 /// of access.
01762 LockKind getLockKindFromAccessKind(AccessKind AK) {
01763   switch (AK) {
01764     case AK_Read :
01765       return LK_Shared;
01766     case AK_Written :
01767       return LK_Exclusive;
01768   }
01769   llvm_unreachable("Unknown AccessKind");
01770 }
01771 
01772 }} // end namespace clang::thread_safety