r182305 - Thread safety analysis: fix use after free bug reported by Evgeniy Stepanov.
DeLesley Hutchins
delesley at google.com
Mon May 20 10:57:55 PDT 2013
Author: delesley
Date: Mon May 20 12:57:55 2013
New Revision: 182305
URL: http://llvm.org/viewvc/llvm-project?rev=182305&view=rev
Log:
Thread safety analysis: fix use after free bug reported by Evgeniy Stepanov.
Modified:
cfe/trunk/lib/Analysis/ThreadSafety.cpp
Modified: cfe/trunk/lib/Analysis/ThreadSafety.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ThreadSafety.cpp?rev=182305&r1=182304&r2=182305&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/ThreadSafety.cpp (original)
+++ cfe/trunk/lib/Analysis/ThreadSafety.cpp Mon May 20 12:57:55 2013
@@ -866,6 +866,16 @@ public:
return false;
}
+ // Returns an iterator
+ iterator findLockIter(FactManager &FM, const SExpr &M) {
+ for (iterator I = begin(), E = end(); I != E; ++I) {
+ const SExpr &Exp = FM[*I].MutID;
+ if (Exp.matches(M))
+ return I;
+ }
+ return end();
+ }
+
LockData* findLock(FactManager &FM, const SExpr &M) const {
for (const_iterator I = begin(), E = end(); I != E; ++I) {
const SExpr &Exp = FM[*I].MutID;
@@ -2189,24 +2199,27 @@ void ThreadSafetyAnalyzer::intersectAndW
bool Modify) {
FactSet FSet1Orig = FSet1;
+ // Find locks in FSet2 that conflict or are not in FSet1, and warn.
for (FactSet::const_iterator I = FSet2.begin(), E = FSet2.end();
I != E; ++I) {
const SExpr &FSet2Mutex = FactMan[*I].MutID;
const LockData &LDat2 = FactMan[*I].LDat;
+ FactSet::iterator I1 = FSet1.findLockIter(FactMan, FSet2Mutex);
- if (LockData *LDat1 = FSet1.findLock(FactMan, FSet2Mutex)) {
+ if (I1 != FSet1.end()) {
+ const LockData* LDat1 = &FactMan[*I1].LDat;
if (LDat1->LKind != LDat2.LKind) {
Handler.handleExclusiveAndShared(FSet2Mutex.toString(),
LDat2.AcquireLoc,
LDat1->AcquireLoc);
if (Modify && LDat1->LKind != LK_Exclusive) {
- FSet1.removeLock(FactMan, FSet2Mutex);
- FSet1.addLock(FactMan, FSet2Mutex, LDat2);
+ // Take the exclusive lock, which is the one in FSet2.
+ *I1 = *I;
}
}
- if (LDat1->Asserted && !LDat2.Asserted) {
- // The non-asserted lock is the one we want to track.
- *LDat1 = LDat2;
+ else if (LDat1->Asserted && !LDat2.Asserted) {
+ // The non-asserted lock in FSet2 is the one we want to track.
+ *I1 = *I;
}
} else {
if (LDat2.UnderlyingMutex.isValid()) {
@@ -2226,7 +2239,8 @@ void ThreadSafetyAnalyzer::intersectAndW
}
}
- for (FactSet::const_iterator I = FSet1.begin(), E = FSet1.end();
+ // Find locks in FSet1 that are not in FSet2, and remove them.
+ for (FactSet::const_iterator I = FSet1Orig.begin(), E = FSet1Orig.end();
I != E; ++I) {
const SExpr &FSet1Mutex = FactMan[*I].MutID;
const LockData &LDat1 = FactMan[*I].LDat;
More information about the cfe-commits
mailing list