diff options
author | Aaron Puchert <aaron.puchert@sap.com> | 2019-01-29 22:11:42 +0000 |
---|---|---|
committer | Aaron Puchert <aaron.puchert@sap.com> | 2019-01-29 22:11:42 +0000 |
commit | ffa1d6ad17159965a2f0c08b4cae40b9a9fa3122 (patch) | |
tree | 1b16e3672b803e2d47379509fe9aa37794a6c5ff /clang/lib | |
parent | d55102a190d490cfd72b19708dfacecb70ac09f5 (diff) | |
download | bcm5719-llvm-ffa1d6ad17159965a2f0c08b4cae40b9a9fa3122.tar.gz bcm5719-llvm-ffa1d6ad17159965a2f0c08b4cae40b9a9fa3122.zip |
Thread safety analysis: Improve diagnostics for double locking
Summary:
We use the existing diag::note_locked_here to tell the user where we saw
the first locking.
Reviewers: aaron.ballman, delesley
Reviewed By: aaron.ballman
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D56967
llvm-svn: 352549
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Analysis/ThreadSafety.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Sema/AnalysisBasedWarnings.cpp | 31 |
2 files changed, 22 insertions, 18 deletions
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp index a2c7ff7f18a..1887e5431ed 100644 --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -873,7 +873,7 @@ public: void handleLock(FactSet &FSet, FactManager &FactMan, const FactEntry &entry, ThreadSafetyHandler &Handler, StringRef DiagKind) const override { - Handler.handleDoubleLock(DiagKind, entry.toString(), entry.loc()); + Handler.handleDoubleLock(DiagKind, entry.toString(), loc(), entry.loc()); } void handleUnlock(FactSet &FSet, FactManager &FactMan, @@ -981,12 +981,13 @@ private: void lock(FactSet &FSet, FactManager &FactMan, const CapabilityExpr &Cp, LockKind kind, SourceLocation loc, ThreadSafetyHandler *Handler, StringRef DiagKind) const { - if (!FSet.findLock(FactMan, Cp)) { + if (const FactEntry *Fact = FSet.findLock(FactMan, Cp)) { + if (Handler) + Handler->handleDoubleLock(DiagKind, Cp.toString(), Fact->loc(), loc); + } else { FSet.removeLock(FactMan, !Cp); FSet.addLock(FactMan, llvm::make_unique<LockableFactEntry>(Cp, kind, loc)); - } else if (Handler) { - Handler->handleDoubleLock(DiagKind, Cp.toString(), loc); } } diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index 8a044d29144..7ce69fd8c19 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -1638,17 +1638,6 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { return ONS; } - // Helper functions - void warnLockMismatch(unsigned DiagID, StringRef Kind, Name LockName, - SourceLocation Loc) { - // Gracefully handle rare cases when the analysis can't get a more - // precise source location. - if (!Loc.isValid()) - Loc = FunLocation; - PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind << LockName); - Warnings.emplace_back(std::move(Warning), getNotes()); - } - public: ThreadSafetyReporter(Sema &S, SourceLocation FL, SourceLocation FEL) : S(S), FunLocation(FL), FunEndLocation(FEL), @@ -1677,7 +1666,11 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { void handleUnmatchedUnlock(StringRef Kind, Name LockName, SourceLocation Loc) override { - warnLockMismatch(diag::warn_unlock_but_no_lock, Kind, LockName, Loc); + if (Loc.isInvalid()) + Loc = FunLocation; + PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_unlock_but_no_lock) + << Kind << LockName); + Warnings.emplace_back(std::move(Warning), getNotes()); } void handleIncorrectUnlockKind(StringRef Kind, Name LockName, @@ -1691,8 +1684,18 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { Warnings.emplace_back(std::move(Warning), getNotes()); } - void handleDoubleLock(StringRef Kind, Name LockName, SourceLocation Loc) override { - warnLockMismatch(diag::warn_double_lock, Kind, LockName, Loc); + void handleDoubleLock(StringRef Kind, Name LockName, SourceLocation LocLocked, + SourceLocation Loc) override { + if (Loc.isInvalid()) + Loc = FunLocation; + PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_double_lock) + << Kind << LockName); + OptionalNotes Notes = + LocLocked.isValid() + ? getNotes(PartialDiagnosticAt( + LocLocked, S.PDiag(diag::note_locked_here) << Kind)) + : getNotes(); + Warnings.emplace_back(std::move(Warning), std::move(Notes)); } void handleMutexHeldEndOfScope(StringRef Kind, Name LockName, |