diff options
author | DeLesley Hutchins <delesley@google.com> | 2014-09-18 23:02:26 +0000 |
---|---|---|
committer | DeLesley Hutchins <delesley@google.com> | 2014-09-18 23:02:26 +0000 |
commit | 9308d1067c5b1dd4faf80d4b572d2f79b6da87c2 (patch) | |
tree | 1ff3e425aa63c71e668723596fe149e820e45a7f /lib/Sema | |
parent | 0e22ee0954f2b8f63bdbe36ba70e3dd1319e5503 (diff) | |
download | clang-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')
-rw-r--r-- | lib/Sema/AnalysisBasedWarnings.cpp | 35 |
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, |