diff options
author | Caitlin Sadowski <supertri@google.com> | 2011-09-14 20:00:24 +0000 |
---|---|---|
committer | Caitlin Sadowski <supertri@google.com> | 2011-09-14 20:00:24 +0000 |
commit | 194418f1db5f5f78bc3e614d1e10a863455d882c (patch) | |
tree | 9a5b76408dc3fb70b800a985087d82ab724c5be4 /lib/Analysis/ThreadSafety.cpp | |
parent | 7c24334bedf59bd9af57ee53eb8f6d9f6a50ca9b (diff) |
Thread safety: adding test cases for unparseable lock expressions and expanding the handling of these expressions
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139720 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ThreadSafety.cpp')
-rw-r--r-- | lib/Analysis/ThreadSafety.cpp | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/lib/Analysis/ThreadSafety.cpp b/lib/Analysis/ThreadSafety.cpp index fe9c5de147..f55211d3cb 100644 --- a/lib/Analysis/ThreadSafety.cpp +++ b/lib/Analysis/ThreadSafety.cpp @@ -154,7 +154,6 @@ public: /// foo(MyL); // requires lock MyL->Mu to be held class MutexID { SmallVector<NamedDecl*, 2> DeclSeq; - ThreadSafetyHandler &Handler; /// Build a Decl sequence representing the lock from the given expression. /// Recursive function that bottoms out when the final DeclRefExpr is reached. @@ -167,20 +166,24 @@ class MutexID { DeclSeq.push_back(ND); buildMutexID(ME->getBase(), Parent); } else if (isa<CXXThisExpr>(Exp)) { - if (!Parent) - return; - buildMutexID(Parent, 0); + if (Parent) + buildMutexID(Parent, 0); + else + return; // mutexID is still valid in this case } else if (CastExpr *CE = dyn_cast<CastExpr>(Exp)) buildMutexID(CE->getSubExpr(), Parent); else - Handler.handleInvalidLockExp(Exp->getExprLoc()); + DeclSeq.clear(); // invalid lock expression } public: - MutexID(ThreadSafetyHandler &Handler, Expr *LExpr, Expr *ParentExpr) - : Handler(Handler) { + MutexID(Expr *LExpr, Expr *ParentExpr) { buildMutexID(LExpr, ParentExpr); - assert(!DeclSeq.empty()); + } + + /// If we encounter part of a lock expression we cannot parse + bool isValid() const { + return !DeclSeq.empty(); } bool operator==(const MutexID &other) const { @@ -206,6 +209,7 @@ public: /// name in diagnostics is a way to get simple, and consistent, mutex names. /// We do not want to output the entire expression text for security reasons. StringRef getName() const { + assert(isValid()); return DeclSeq.front()->getName(); } @@ -324,7 +328,12 @@ public: void BuildLockset::addLock(SourceLocation LockLoc, Expr *LockExp, Expr *Parent, LockKind LK) { // FIXME: deal with acquired before/after annotations - MutexID Mutex(Handler, LockExp, Parent); + MutexID Mutex(LockExp, Parent); + if (!Mutex.isValid()) { + Handler.handleInvalidLockExp(LockExp->getExprLoc()); + return; + } + LockData NewLock(LockLoc, LK); // FIXME: Don't always warn when we have support for reentrant locks. @@ -338,7 +347,11 @@ void BuildLockset::addLock(SourceLocation LockLoc, Expr *LockExp, Expr *Parent, /// \param UnlockLoc The source location of the unlock (only used in error msg) void BuildLockset::removeLock(SourceLocation UnlockLoc, Expr *LockExp, Expr *Parent) { - MutexID Mutex(Handler, LockExp, Parent); + MutexID Mutex(LockExp, Parent); + if (!Mutex.isValid()) { + Handler.handleInvalidLockExp(LockExp->getExprLoc()); + return; + } Lockset NewLSet = LocksetFactory.remove(LSet, Mutex); if(NewLSet == LSet) @@ -365,8 +378,10 @@ void BuildLockset::warnIfMutexNotHeld(const NamedDecl *D, Expr *Exp, ProtectedOperationKind POK) { LockKind LK = getLockKindFromAccessKind(AK); Expr *Parent = getParent(Exp); - MutexID Mutex(Handler, MutexExp, Parent); - if (!locksetContainsAtLeast(Mutex, LK)) + MutexID Mutex(MutexExp, Parent); + if (!Mutex.isValid()) + Handler.handleInvalidLockExp(MutexExp->getExprLoc()); + else if (!locksetContainsAtLeast(Mutex, LK)) Handler.handleMutexNotHeld(D, POK, Mutex.getName(), LK, Exp->getExprLoc()); } @@ -467,7 +482,7 @@ void BuildLockset::addLocksToSet(LockKind LK, Attr *Attr, if (SpecificAttr->args_size() == 0) { // The mutex held is the "this" object. - addLock(ExpLocation, Parent, Parent, LK); + addLock(ExpLocation, Parent, 0, LK); return; } @@ -517,7 +532,7 @@ void BuildLockset::VisitCXXMemberCallExpr(CXXMemberCallExpr *Exp) { UnlockFunctionAttr *UFAttr = cast<UnlockFunctionAttr>(Attr); if (UFAttr->args_size() == 0) { // The lock held is the "this" object. - removeLock(ExpLocation, Parent, Parent); + removeLock(ExpLocation, Parent, 0); break; } @@ -556,8 +571,10 @@ void BuildLockset::VisitCXXMemberCallExpr(CXXMemberCallExpr *Exp) { LocksExcludedAttr *LEAttr = cast<LocksExcludedAttr>(Attr); for (LocksExcludedAttr::args_iterator I = LEAttr->args_begin(), E = LEAttr->args_end(); I != E; ++I) { - MutexID Mutex(Handler, *I, Parent); - if (locksetContains(Mutex)) + MutexID Mutex(*I, Parent); + if (!Mutex.isValid()) + Handler.handleInvalidLockExp((*I)->getExprLoc()); + else if (locksetContains(Mutex)) Handler.handleFunExcludesLock(D->getName(), Mutex.getName(), ExpLocation); } |