diff options
author | DeLesley Hutchins <delesley@google.com> | 2014-08-14 21:40:15 +0000 |
---|---|---|
committer | DeLesley Hutchins <delesley@google.com> | 2014-08-14 21:40:15 +0000 |
commit | eb0ea5f40a48c488cb8973490c41713eb202904d (patch) | |
tree | 67838dbd25128f56a18fd62e336648eb50caad14 /clang/lib/Sema/AnalysisBasedWarnings.cpp | |
parent | 61c386126ba1b06ceb8513e9b7f872482c0ff62f (diff) | |
download | bcm5719-llvm-eb0ea5f40a48c488cb8973490c41713eb202904d.tar.gz bcm5719-llvm-eb0ea5f40a48c488cb8973490c41713eb202904d.zip |
Thread safety analysis: add -Wthread-safety-verbose flag, which adds additional notes that are helpful when compiling statistics on thread safety warnings.
llvm-svn: 215677
Diffstat (limited to 'clang/lib/Sema/AnalysisBasedWarnings.cpp')
-rw-r--r-- | clang/lib/Sema/AnalysisBasedWarnings.cpp | 72 |
1 files changed, 60 insertions, 12 deletions
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index 59d13de8309..93ee16b4c52 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -1451,6 +1451,30 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { DiagList Warnings; SourceLocation FunLocation, FunEndLocation; + const FunctionDecl *CurrentFunction; + bool Verbose; + + OptionalNotes getNotes() { + if (Verbose && CurrentFunction) { + PartialDiagnosticAt FNote(CurrentFunction->getBody()->getLocStart(), + S.PDiag(diag::note_thread_warning_in_fun) + << CurrentFunction->getNameAsString()); + return OptionalNotes(1, FNote); + } + else return OptionalNotes(); + } + + OptionalNotes getNotes(const PartialDiagnosticAt &Note) { + OptionalNotes ONS(1, Note); + if (Verbose && CurrentFunction) { + PartialDiagnosticAt FNote(CurrentFunction->getBody()->getLocStart(), + S.PDiag(diag::note_thread_warning_in_fun) + << CurrentFunction->getNameAsString()); + ONS.push_back(FNote); + } + return ONS; + } + // Helper functions void warnLockMismatch(unsigned DiagID, StringRef Kind, Name LockName, SourceLocation Loc) { @@ -1459,12 +1483,15 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { if (!Loc.isValid()) Loc = FunLocation; PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind << LockName); - Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); + Warnings.push_back(DelayedDiag(Warning, getNotes())); } public: ThreadSafetyReporter(Sema &S, SourceLocation FL, SourceLocation FEL) - : S(S), FunLocation(FL), FunEndLocation(FEL) {} + : S(S), FunLocation(FL), FunEndLocation(FEL), + CurrentFunction(nullptr), Verbose(false) {} + + void setVerbose(bool b) { Verbose = b; } /// \brief Emit all buffered diagnostics in order of sourcelocation. /// We need to output diagnostics produced while iterating through @@ -1482,12 +1509,14 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { void handleInvalidLockExp(StringRef Kind, SourceLocation Loc) override { PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_cannot_resolve_lock) << Loc); - Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); + Warnings.push_back(DelayedDiag(Warning, getNotes())); } + void handleUnmatchedUnlock(StringRef Kind, Name LockName, SourceLocation Loc) override { warnLockMismatch(diag::warn_unlock_but_no_lock, Kind, LockName, Loc); } + void handleIncorrectUnlockKind(StringRef Kind, Name LockName, LockKind Expected, LockKind Received, SourceLocation Loc) override { @@ -1496,8 +1525,9 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_unlock_kind_mismatch) << Kind << LockName << Received << Expected); - Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); + Warnings.push_back(DelayedDiag(Warning, getNotes())); } + void handleDoubleLock(StringRef Kind, Name LockName, SourceLocation Loc) override { warnLockMismatch(diag::warn_double_lock, Kind, LockName, Loc); } @@ -1529,10 +1559,10 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { if (LocLocked.isValid()) { PartialDiagnosticAt Note(LocLocked, S.PDiag(diag::note_locked_here) << Kind); - Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note))); + Warnings.push_back(DelayedDiag(Warning, getNotes(Note))); return; } - Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); + Warnings.push_back(DelayedDiag(Warning, getNotes())); } void handleExclusiveAndShared(StringRef Kind, Name LockName, @@ -1543,7 +1573,7 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { << Kind << LockName); PartialDiagnosticAt Note(Loc2, S.PDiag(diag::note_lock_exclusive_and_shared) << Kind << LockName); - Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note))); + Warnings.push_back(DelayedDiag(Warning, getNotes(Note))); } void handleNoMutexHeld(StringRef Kind, const NamedDecl *D, @@ -1556,7 +1586,7 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { diag::warn_var_deref_requires_any_lock; PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << D->getNameAsString() << getLockKindFromAccessKind(AK)); - Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); + Warnings.push_back(DelayedDiag(Warning, getNotes())); } void handleMutexNotHeld(StringRef Kind, const NamedDecl *D, @@ -1581,7 +1611,7 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { << LockName << LK); PartialDiagnosticAt Note(Loc, S.PDiag(diag::note_found_mutex_near_match) << *PossibleMatch); - Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note))); + Warnings.push_back(DelayedDiag(Warning, getNotes(Note))); } else { switch (POK) { case POK_VarAccess: @@ -1597,7 +1627,15 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind << D->getNameAsString() << LockName << LK); - Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); + if (Verbose && POK == POK_VarAccess) { + PartialDiagnosticAt Note(D->getLocation(), + S.PDiag(diag::note_guarded_by_declared_here) << + D->getNameAsString()); + Warnings.push_back(DelayedDiag(Warning, getNotes(Note))); + } + else { + Warnings.push_back(DelayedDiag(Warning, getNotes())); + } } } @@ -1606,7 +1644,7 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_acquire_requires_negative_cap) << Kind << LockName << Neg); - Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); + Warnings.push_back(DelayedDiag(Warning, getNotes())); } @@ -1614,7 +1652,15 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler { SourceLocation Loc) override { PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_fun_excludes_mutex) << Kind << FunName << LockName); - Warnings.push_back(DelayedDiag(Warning, OptionalNotes())); + Warnings.push_back(DelayedDiag(Warning, getNotes())); + } + + void enterFunction(const FunctionDecl* FD) override { + CurrentFunction = FD; + } + + void leaveFunction(const FunctionDecl* FD) override { + CurrentFunction = 0; } }; @@ -1908,6 +1954,8 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P, threadSafety::ThreadSafetyReporter Reporter(S, FL, FEL); if (!Diags.isIgnored(diag::warn_thread_safety_beta, D->getLocStart())) Reporter.setIssueBetaWarnings(true); + if (!Diags.isIgnored(diag::warn_thread_safety_verbose, D->getLocStart())) + Reporter.setVerbose(true); threadSafety::runThreadSafetyAnalysis(AC, Reporter); Reporter.emitDiagnostics(); |