summaryrefslogtreecommitdiff
path: root/lib/Sema/AnalysisBasedWarnings.cpp
diff options
context:
space:
mode:
authorDeLesley Hutchins <delesley@google.com>2014-09-18 23:02:26 +0000
committerDeLesley Hutchins <delesley@google.com>2014-09-18 23:02:26 +0000
commit9308d1067c5b1dd4faf80d4b572d2f79b6da87c2 (patch)
tree1ff3e425aa63c71e668723596fe149e820e45a7f /lib/Sema/AnalysisBasedWarnings.cpp
parent0e22ee0954f2b8f63bdbe36ba70e3dd1319e5503 (diff)
downloadclang-9308d1067c5b1dd4faf80d4b572d2f79b6da87c2.tar.gz
Thread Safety Analysis: add new warning flag, -Wthread-safety-reference, which
warns when a guarded variable is passed by reference as a function argument. This is released as a separate warning flag, because it could potentially break existing code that uses thread safety analysis. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@218087 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/AnalysisBasedWarnings.cpp')
-rw-r--r--lib/Sema/AnalysisBasedWarnings.cpp35
1 files changed, 34 insertions, 1 deletions
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp
index 20b7a0240d..b207df9fc5 100644
--- a/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/lib/Sema/AnalysisBasedWarnings.cpp
@@ -1475,6 +1475,20 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {
return ONS;
}
+ OptionalNotes getNotes(const PartialDiagnosticAt &Note1,
+ const PartialDiagnosticAt &Note2) const {
+ OptionalNotes ONS;
+ ONS.push_back(Note1);
+ ONS.push_back(Note2);
+ 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) {
@@ -1605,13 +1619,25 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {
case POK_FunctionCall:
DiagID = diag::warn_fun_requires_lock_precise;
break;
+ case POK_PassByRef:
+ DiagID = diag::warn_guarded_pass_by_reference;
+ break;
+ case POK_PtPassByRef:
+ DiagID = diag::warn_pt_guarded_pass_by_reference;
+ break;
}
PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind
<< D->getNameAsString()
<< LockName << LK);
PartialDiagnosticAt Note(Loc, S.PDiag(diag::note_found_mutex_near_match)
<< *PossibleMatch);
- Warnings.push_back(DelayedDiag(Warning, getNotes(Note)));
+ if (Verbose && POK == POK_VarAccess) {
+ PartialDiagnosticAt VNote(D->getLocation(),
+ S.PDiag(diag::note_guarded_by_declared_here)
+ << D->getNameAsString());
+ Warnings.push_back(DelayedDiag(Warning, getNotes(Note, VNote)));
+ } else
+ Warnings.push_back(DelayedDiag(Warning, getNotes(Note)));
} else {
switch (POK) {
case POK_VarAccess:
@@ -1623,6 +1649,12 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {
case POK_FunctionCall:
DiagID = diag::warn_fun_requires_lock;
break;
+ case POK_PassByRef:
+ DiagID = diag::warn_guarded_pass_by_reference;
+ break;
+ case POK_PtPassByRef:
+ DiagID = diag::warn_pt_guarded_pass_by_reference;
+ break;
}
PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind
<< D->getNameAsString()
@@ -1637,6 +1669,7 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {
}
}
+
virtual void handleNegativeNotHeld(StringRef Kind, Name LockName, Name Neg,
SourceLocation Loc) {
PartialDiagnosticAt Warning(Loc,