r188505 - Thread Safety Analysis: fix bug when using TryLock with && and || expressions.
DeLesley Hutchins
delesley at google.com
Thu Aug 15 16:06:34 PDT 2013
Author: delesley
Date: Thu Aug 15 18:06:33 2013
New Revision: 188505
URL: http://llvm.org/viewvc/llvm-project?rev=188505&view=rev
Log:
Thread Safety Analysis: fix bug when using TryLock with && and || expressions.
Modified:
cfe/trunk/lib/Analysis/ThreadSafety.cpp
cfe/trunk/test/SemaCXX/warn-thread-safety-analysis.cpp
Modified: cfe/trunk/lib/Analysis/ThreadSafety.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ThreadSafety.cpp?rev=188505&r1=188504&r2=188505&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/ThreadSafety.cpp (original)
+++ cfe/trunk/lib/Analysis/ThreadSafety.cpp Thu Aug 15 18:06:33 2013
@@ -1660,15 +1660,22 @@ const CallExpr* ThreadSafetyAnalyzer::ge
if (!TCond) Negate = !Negate;
return getTrylockCallExpr(BOP->getLHS(), C, Negate);
}
- else if (getStaticBooleanValue(BOP->getLHS(), TCond)) {
+ TCond = false;
+ if (getStaticBooleanValue(BOP->getLHS(), TCond)) {
if (!TCond) Negate = !Negate;
return getTrylockCallExpr(BOP->getRHS(), C, Negate);
}
return 0;
}
+ if (BOP->getOpcode() == BO_LAnd) {
+ // LHS must have been evaluated in a different block.
+ return getTrylockCallExpr(BOP->getRHS(), C, Negate);
+ }
+ if (BOP->getOpcode() == BO_LOr) {
+ return getTrylockCallExpr(BOP->getRHS(), C, Negate);
+ }
return 0;
}
- // FIXME -- handle && and || as well.
return 0;
}
@@ -1682,11 +1689,11 @@ void ThreadSafetyAnalyzer::getEdgeLockse
const CFGBlock *CurrBlock) {
Result = ExitSet;
- if (!PredBlock->getTerminatorCondition())
+ const Stmt *Cond = PredBlock->getTerminatorCondition();
+ if (!Cond)
return;
bool Negate = false;
- const Stmt *Cond = PredBlock->getTerminatorCondition();
const CFGBlockInfo *PredBlockInfo = &BlockInfo[PredBlock->getBlockID()];
const LocalVarContext &LVarCtx = PredBlockInfo->ExitContext;
@@ -1699,7 +1706,6 @@ void ThreadSafetyAnalyzer::getEdgeLockse
if(!FunDecl || !FunDecl->hasAttrs())
return;
-
MutexIDList ExclusiveLocksToAdd;
MutexIDList SharedLocksToAdd;
Modified: cfe/trunk/test/SemaCXX/warn-thread-safety-analysis.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-thread-safety-analysis.cpp?rev=188505&r1=188504&r2=188505&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-thread-safety-analysis.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-thread-safety-analysis.cpp Thu Aug 15 18:06:33 2013
@@ -107,14 +107,14 @@ class MutexWrapper {
public:
Mutex mu;
int x __attribute__((guarded_by(mu)));
- void MyLock() __attribute__((exclusive_lock_function(mu)));
+ void MyLock() __attribute__((exclusive_lock_function(mu)));
};
MutexWrapper sls_mw;
void sls_fun_0() {
sls_mw.mu.Lock();
- sls_mw.x = 5;
+ sls_mw.x = 5;
sls_mw.mu.Unlock();
}
@@ -3074,44 +3074,6 @@ void Foo::test1() {
#endif
}
-
-void Foo::test2() {
-/* FIXME: these tests depend on changes to the CFG.
- *
- if (mu_.TryLock() && c) {
- a = 0;
- unlock();
- }
- else return;
-
- if (c && mu_.TryLock()) {
- a = 0;
- unlock();
- }
- else return;
-
- if (!(mu_.TryLock() && c))
- return;
- a = 0;
- unlock();
-
- if (!(c && mu_.TryLock()))
- return;
- a = 0;
- unlock();
-
- if (!(mu_.TryLock() == 0) && c) {
- a = 0;
- unlock();
- }
-
- if (!mu_.TryLock() || c)
- return;
- a = 0;
- unlock();
-*/
-}
-
} // end namespace TryLockEqTest
@@ -4092,3 +4054,84 @@ public:
} // end namespace AssertHeldTest
+namespace LogicalConditionalTryLock {
+
+class Foo {
+public:
+ Mutex mu;
+ int a GUARDED_BY(mu);
+ bool c;
+
+ bool newc();
+
+ void test1() {
+ if (c && mu.TryLock()) {
+ a = 0;
+ mu.Unlock();
+ }
+ }
+
+ void test2() {
+ bool b = mu.TryLock();
+ if (c && b) {
+ a = 0;
+ mu.Unlock();
+ }
+ }
+
+ void test3() {
+ if (c || !mu.TryLock())
+ return;
+ a = 0;
+ mu.Unlock();
+ }
+
+ void test4() {
+ while (c && mu.TryLock()) {
+ a = 0;
+ c = newc();
+ mu.Unlock();
+ }
+ }
+
+ void test5() {
+ while (c) {
+ if (newc() || !mu.TryLock())
+ break;
+ a = 0;
+ mu.Unlock();
+ }
+ }
+
+ void test6() {
+ mu.Lock();
+ do {
+ a = 0;
+ mu.Unlock();
+ } while (newc() && mu.TryLock());
+ }
+
+ void test7() {
+ for (bool b = mu.TryLock(); c && b;) {
+ a = 0;
+ mu.Unlock();
+ }
+ }
+
+ void test8() {
+ if (c && newc() && mu.TryLock()) {
+ a = 0;
+ mu.Unlock();
+ }
+ }
+
+ void test9() {
+ if (!(c && newc() && mu.TryLock()))
+ return;
+ a = 0;
+ mu.Unlock();
+ }
+};
+
+} // end namespace LogicalConditionalTryLock
+
More information about the cfe-commits
mailing list