diff options
author | DeLesley Hutchins <delesley@google.com> | 2012-07-02 22:26:29 +0000 |
---|---|---|
committer | DeLesley Hutchins <delesley@google.com> | 2012-07-02 22:26:29 +0000 |
commit | ab0d4e6cd881ae078bcba512b6dfceffc02a375b (patch) | |
tree | e45284e511270fb82bfd63c4aca544b6290b3d3b /clang/lib/Analysis/ThreadSafety.cpp | |
parent | a4ee064cf361a0ad6f9d07276afb31801fa77b7a (diff) | |
download | bcm5719-llvm-ab0d4e6cd881ae078bcba512b6dfceffc02a375b.tar.gz bcm5719-llvm-ab0d4e6cd881ae078bcba512b6dfceffc02a375b.zip |
Thread safety analysis: fixed bug that occurs when very silly people
use scoped_lockable without putting unlock_function on the
destructor.
llvm-svn: 159609
Diffstat (limited to 'clang/lib/Analysis/ThreadSafety.cpp')
-rw-r--r-- | clang/lib/Analysis/ThreadSafety.cpp | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp index b82bc55dffd..f9d93ee0dfa 100644 --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -1558,20 +1558,29 @@ Lockset ThreadSafetyAnalyzer::intersectAndWarn(const Lockset &LSet1, for (Lockset::iterator I = LSet2.begin(), E = LSet2.end(); I != E; ++I) { const MutexID &LSet2Mutex = I.getKey(); - const LockData &LSet2LockData = I.getData(); - if (const LockData *LD = LSet1.lookup(LSet2Mutex)) { - if (LD->LKind != LSet2LockData.LKind) { + const LockData &LDat2 = I.getData(); + if (const LockData *LDat1 = LSet1.lookup(LSet2Mutex)) { + if (LDat1->LKind != LDat2.LKind) { Handler.handleExclusiveAndShared(LSet2Mutex.getName(), - LSet2LockData.AcquireLoc, - LD->AcquireLoc); - if (LD->LKind != LK_Exclusive) - Intersection = LocksetFactory.add(Intersection, LSet2Mutex, - LSet2LockData); + LDat2.AcquireLoc, + LDat1->AcquireLoc); + if (LDat1->LKind != LK_Exclusive) + Intersection = LocksetFactory.add(Intersection, LSet2Mutex, LDat2); } } else { - if (!LSet2LockData.Managed) + if (LDat2.UnderlyingMutex.isValid()) { + if (LSet2.lookup(LDat2.UnderlyingMutex)) { + // If this is a scoped lock that manages another mutex, and if the + // underlying mutex is still held, then warn about the underlying + // mutex. + Handler.handleMutexHeldEndOfScope(LDat2.UnderlyingMutex.getName(), + LDat2.AcquireLoc, + JoinLoc, LEK1); + } + } + else if (!LDat2.Managed) Handler.handleMutexHeldEndOfScope(LSet2Mutex.getName(), - LSet2LockData.AcquireLoc, + LDat2.AcquireLoc, JoinLoc, LEK1); } } @@ -1579,11 +1588,21 @@ Lockset ThreadSafetyAnalyzer::intersectAndWarn(const Lockset &LSet1, for (Lockset::iterator I = LSet1.begin(), E = LSet1.end(); I != E; ++I) { if (!LSet2.contains(I.getKey())) { const MutexID &Mutex = I.getKey(); - const LockData &MissingLock = I.getData(); - - if (!MissingLock.Managed) + const LockData &LDat1 = I.getData(); + + if (LDat1.UnderlyingMutex.isValid()) { + if (LSet1.lookup(LDat1.UnderlyingMutex)) { + // If this is a scoped lock that manages another mutex, and if the + // underlying mutex is still held, then warn about the underlying + // mutex. + Handler.handleMutexHeldEndOfScope(LDat1.UnderlyingMutex.getName(), + LDat1.AcquireLoc, + JoinLoc, LEK1); + } + } + else if (!LDat1.Managed) Handler.handleMutexHeldEndOfScope(Mutex.getName(), - MissingLock.AcquireLoc, + LDat1.AcquireLoc, JoinLoc, LEK2); Intersection = LocksetFactory.remove(Intersection, Mutex); } |