[llvm-branch-commits] [clang] release/21.x: Thread safety analysis: Don't warn on acquiring reentrant capability (#150857) (PR #151889)
Tobias Hieta via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Aug 5 01:56:48 PDT 2025
https://github.com/tru updated https://github.com/llvm/llvm-project/pull/151889
>From d4046ae6df51ad41370dfe474bfb3c93fd8e166d Mon Sep 17 00:00:00 2001
From: Aaron Puchert <aaronpuchert at alice-dsl.net>
Date: Sun, 3 Aug 2025 19:50:17 +0200
Subject: [PATCH] Thread safety analysis: Don't warn on acquiring reentrant
capability (#150857)
The point of reentrant capabilities is that they can be acquired
multiple times, so they should probably be excluded from requiring a
negative capability on acquisition via -Wthread-safety-negative.
However, we still propagate explicit negative requirements.
(cherry picked from commit a048aeb06e5de571eadd646860c320b9a67d1efc)
---
clang/lib/Analysis/ThreadSafety.cpp | 2 +-
.../SemaCXX/warn-thread-safety-negative.cpp | 32 +++++++++++++++++++
2 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp
index 80e7c8eff671a..dadb0b757a2c8 100644
--- a/clang/lib/Analysis/ThreadSafety.cpp
+++ b/clang/lib/Analysis/ThreadSafety.cpp
@@ -1331,7 +1331,7 @@ void ThreadSafetyAnalyzer::addLock(FactSet &FSet,
FSet.removeLock(FactMan, NegC);
}
else {
- if (inCurrentScope(*Entry) && !Entry->asserted())
+ if (inCurrentScope(*Entry) && !Entry->asserted() && !Entry->reentrant())
Handler.handleNegativeNotHeld(Entry->getKind(), Entry->toString(),
NegC.toString(), Entry->loc());
}
diff --git a/clang/test/SemaCXX/warn-thread-safety-negative.cpp b/clang/test/SemaCXX/warn-thread-safety-negative.cpp
index 9eabd67e4fc76..0caf6d6139e58 100644
--- a/clang/test/SemaCXX/warn-thread-safety-negative.cpp
+++ b/clang/test/SemaCXX/warn-thread-safety-negative.cpp
@@ -21,6 +21,15 @@ class LOCKABLE Mutex {
void AssertReaderHeld() ASSERT_SHARED_LOCK();
};
+class LOCKABLE REENTRANT_CAPABILITY ReentrantMutex {
+public:
+ void Lock() EXCLUSIVE_LOCK_FUNCTION();
+ void Unlock() UNLOCK_FUNCTION();
+
+ // for negative capabilities
+ const ReentrantMutex& operator!() const { return *this; }
+};
+
class SCOPED_LOCKABLE MutexLock {
public:
MutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);
@@ -89,6 +98,29 @@ class Foo {
}
};
+class Reentrant {
+ ReentrantMutex mu;
+
+public:
+ void acquire() {
+ mu.Lock(); // no warning -- reentrant mutex
+ mu.Unlock();
+ }
+
+ void requireNegative() EXCLUSIVE_LOCKS_REQUIRED(!mu) { // warning?
+ mu.Lock();
+ mu.Unlock();
+ }
+
+ void callRequireNegative() {
+ requireNegative(); // expected-warning{{calling function 'requireNegative' requires negative capability '!mu'}}
+ }
+
+ void callHaveNegative() EXCLUSIVE_LOCKS_REQUIRED(!mu) {
+ requireNegative();
+ }
+};
+
} // end namespace SimpleTest
Mutex globalMutex;
More information about the llvm-branch-commits
mailing list