diff options
author | DeLesley Hutchins <delesley@google.com> | 2012-07-02 22:16:54 +0000 |
---|---|---|
committer | DeLesley Hutchins <delesley@google.com> | 2012-07-02 22:16:54 +0000 |
commit | 6e6dbb76180bf9ee9d45fc5b69eadfa16a54dd6c (patch) | |
tree | 152266425cbb5f47363030191f736d819f023cbb | |
parent | 2a15baf9683d29849cbc82c6f972d338927609b8 (diff) | |
download | bcm5719-llvm-6e6dbb76180bf9ee9d45fc5b69eadfa16a54dd6c.tar.gz bcm5719-llvm-6e6dbb76180bf9ee9d45fc5b69eadfa16a54dd6c.zip |
Thread safety analysis: fixed incorrect error message at the end of a locks_required function.
llvm-svn: 159607
-rw-r--r-- | clang/include/clang/Analysis/Analyses/ThreadSafety.h | 3 | ||||
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | clang/lib/Analysis/ThreadSafety.cpp | 21 | ||||
-rw-r--r-- | clang/lib/Sema/AnalysisBasedWarnings.cpp | 3 | ||||
-rw-r--r-- | clang/test/SemaCXX/warn-thread-safety-analysis.cpp | 16 |
5 files changed, 39 insertions, 7 deletions
diff --git a/clang/include/clang/Analysis/Analyses/ThreadSafety.h b/clang/include/clang/Analysis/Analyses/ThreadSafety.h index beb1938f859..742cc043445 100644 --- a/clang/include/clang/Analysis/Analyses/ThreadSafety.h +++ b/clang/include/clang/Analysis/Analyses/ThreadSafety.h @@ -60,7 +60,8 @@ enum AccessKind { enum LockErrorKind { LEK_LockedSomeLoopIterations, LEK_LockedSomePredecessors, - LEK_LockedAtEndOfFunction + LEK_LockedAtEndOfFunction, + LEK_NotLockedAtEndOfFunction }; /// Handler class for thread safety warnings. diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 18b36e512f3..66ae44fb281 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1775,6 +1775,9 @@ def warn_double_lock : Warning< def warn_no_unlock : Warning< "mutex '%0' is still locked at the end of function">, InGroup<ThreadSafetyAnalysis>, DefaultIgnore; +def warn_expecting_locked : Warning< + "expecting mutex '%0' to be locked at the end of function">, + InGroup<ThreadSafetyAnalysis>, DefaultIgnore; // FIXME: improve the error message about locks not in scope def warn_lock_some_predecessors : Warning< "mutex '%0' is not locked on every path through here">, diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp index e29b2a9d069..b82bc55dffd 100644 --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -951,7 +951,13 @@ public: const CFGBlock *CurrBlock); Lockset intersectAndWarn(const Lockset &LSet1, const Lockset &LSet2, - SourceLocation JoinLoc, LockErrorKind LEK); + SourceLocation JoinLoc, + LockErrorKind LEK1, LockErrorKind LEK2); + + Lockset intersectAndWarn(const Lockset &LSet1, const Lockset &LSet2, + SourceLocation JoinLoc, LockErrorKind LEK1) { + return intersectAndWarn(LSet1, LSet2, JoinLoc, LEK1, LEK1); + } void runAnalysis(AnalysisDeclContext &AC); }; @@ -1541,11 +1547,13 @@ void BuildLockset::VisitDeclStmt(DeclStmt *S) { /// \param LSet1 The first lockset. /// \param LSet2 The second lockset. /// \param JoinLoc The location of the join point for error reporting -/// \param LEK The error message to report. +/// \param LEK1 The error message to report if a mutex is missing from LSet1 +/// \param LEK2 The error message to report if a mutex is missing from Lset2 Lockset ThreadSafetyAnalyzer::intersectAndWarn(const Lockset &LSet1, const Lockset &LSet2, SourceLocation JoinLoc, - LockErrorKind LEK) { + LockErrorKind LEK1, + LockErrorKind LEK2) { Lockset Intersection = LSet1; for (Lockset::iterator I = LSet2.begin(), E = LSet2.end(); I != E; ++I) { @@ -1564,7 +1572,7 @@ Lockset ThreadSafetyAnalyzer::intersectAndWarn(const Lockset &LSet1, if (!LSet2LockData.Managed) Handler.handleMutexHeldEndOfScope(LSet2Mutex.getName(), LSet2LockData.AcquireLoc, - JoinLoc, LEK); + JoinLoc, LEK1); } } @@ -1576,7 +1584,7 @@ Lockset ThreadSafetyAnalyzer::intersectAndWarn(const Lockset &LSet1, if (!MissingLock.Managed) Handler.handleMutexHeldEndOfScope(Mutex.getName(), MissingLock.AcquireLoc, - JoinLoc, LEK); + JoinLoc, LEK2); Intersection = LocksetFactory.remove(Intersection, Mutex); } } @@ -1818,7 +1826,8 @@ void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) { // FIXME: Should we call this function for all blocks which exit the function? intersectAndWarn(Initial->EntrySet, Final->ExitSet, Final->ExitLoc, - LEK_LockedAtEndOfFunction); + LEK_LockedAtEndOfFunction, + LEK_NotLockedAtEndOfFunction); } } // end anonymous namespace diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index 1d74d7f765b..d696283f7f5 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -1061,6 +1061,9 @@ class ThreadSafetyReporter : public clang::thread_safety::ThreadSafetyHandler { case LEK_LockedAtEndOfFunction: DiagID = diag::warn_no_unlock; break; + case LEK_NotLockedAtEndOfFunction: + DiagID = diag::warn_expecting_locked; + break; } if (LocEndOfScope.isInvalid()) LocEndOfScope = FunEndLocation; diff --git a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp index 53f3bee2ac7..35a2dd01214 100644 --- a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -2451,6 +2451,22 @@ void Foo::foo() EXCLUSIVE_LOCKS_REQUIRED(mu_) { }; +namespace UnlockBug { +class Foo { +public: + Mutex mutex_; + + void foo1() EXCLUSIVE_LOCKS_REQUIRED(mutex_) { // expected-note {{mutex acquired here}} + mutex_.Unlock(); + } // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}} + + + void foo2() SHARED_LOCKS_REQUIRED(mutex_) { // expected-note {{mutex acquired here}} + mutex_.Unlock(); + } // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}} +}; + +} // end namespace UnlockBug |