summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/AnalysisBasedWarnings.cpp
diff options
context:
space:
mode:
authorDeLesley Hutchins <delesley@google.com>2014-08-14 21:40:15 +0000
committerDeLesley Hutchins <delesley@google.com>2014-08-14 21:40:15 +0000
commiteb0ea5f40a48c488cb8973490c41713eb202904d (patch)
tree67838dbd25128f56a18fd62e336648eb50caad14 /clang/lib/Sema/AnalysisBasedWarnings.cpp
parent61c386126ba1b06ceb8513e9b7f872482c0ff62f (diff)
downloadbcm5719-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.cpp72
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();
OpenPOWER on IntegriCloud