aboutsummaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/AnalysisBasedWarnings.cpp25
-rw-r--r--clang/test/SemaCXX/warn-thread-safety-analysis.cpp14
2 files changed, 34 insertions, 5 deletions
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 5e75c64..5eba024 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -2112,11 +2112,26 @@ class ThreadSafetyReporter : public clang::threadSafety::ThreadSafetyHandler {
void handleNoMutexHeld(const NamedDecl *D, ProtectedOperationKind POK,
AccessKind AK, SourceLocation Loc) override {
- assert((POK == POK_VarAccess || POK == POK_VarDereference) &&
- "Only works for variables");
- unsigned DiagID = POK == POK_VarAccess?
- diag::warn_variable_requires_any_lock:
- diag::warn_var_deref_requires_any_lock;
+ unsigned DiagID = 0;
+ switch (POK) {
+ case POK_VarAccess:
+ case POK_PassByRef:
+ case POK_ReturnByRef:
+ case POK_PassPointer:
+ case POK_ReturnPointer:
+ DiagID = diag::warn_variable_requires_any_lock;
+ break;
+ case POK_VarDereference:
+ case POK_PtPassByRef:
+ case POK_PtReturnByRef:
+ case POK_PtPassPointer:
+ case POK_PtReturnPointer:
+ DiagID = diag::warn_var_deref_requires_any_lock;
+ break;
+ case POK_FunctionCall:
+ llvm_unreachable("Only works for variables");
+ break;
+ }
PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID)
<< D << getLockKindFromAccessKind(AK));
Warnings.emplace_back(std::move(Warning), getNotes());
diff --git a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp
index d64ed1e..d82e248 100644
--- a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp
+++ b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp
@@ -6196,6 +6196,8 @@ class Return {
Mutex mu;
Foo foo GUARDED_BY(mu);
Foo* foo_ptr PT_GUARDED_BY(mu);
+ Foo foo_depr GUARDED_VAR; // test deprecated attribute
+ Foo* foo_ptr_depr PT_GUARDED_VAR; // test deprecated attribute
Foo returns_value_locked() {
MutexLock lock(&mu);
@@ -6297,6 +6299,18 @@ class Return {
return *foo_ptr; // expected-warning {{returning the value that 'foo_ptr' points to by reference requires holding mutex 'mu' exclusively}}
}
+ Foo *returns_ptr_deprecated() {
+ return &foo_depr; // expected-warning {{writing variable 'foo_depr' requires holding any mutex exclusively}}
+ }
+
+ Foo *returns_pt_ptr_deprecated() {
+ return foo_ptr_depr; // expected-warning {{writing the value pointed to by 'foo_ptr_depr' requires holding any mutex exclusively}}
+ }
+
+ Foo &returns_ref_deprecated() {
+ return *foo_ptr_depr; // expected-warning {{writing the value pointed to by 'foo_ptr_depr' requires holding any mutex exclusively}}
+ }
+
// FIXME: Basic alias analysis would help catch cases like below.
Foo *returns_ptr_alias() {
mu.Lock();