Skip to content

Commit d4046ae

Browse files
aaronpucherttru
authored andcommitted
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 a048aeb)
1 parent f5ad8dc commit d4046ae

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

clang/lib/Analysis/ThreadSafety.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1331,7 +1331,7 @@ void ThreadSafetyAnalyzer::addLock(FactSet &FSet,
13311331
FSet.removeLock(FactMan, NegC);
13321332
}
13331333
else {
1334-
if (inCurrentScope(*Entry) && !Entry->asserted())
1334+
if (inCurrentScope(*Entry) && !Entry->asserted() && !Entry->reentrant())
13351335
Handler.handleNegativeNotHeld(Entry->getKind(), Entry->toString(),
13361336
NegC.toString(), Entry->loc());
13371337
}

clang/test/SemaCXX/warn-thread-safety-negative.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ class LOCKABLE Mutex {
2121
void AssertReaderHeld() ASSERT_SHARED_LOCK();
2222
};
2323

24+
class LOCKABLE REENTRANT_CAPABILITY ReentrantMutex {
25+
public:
26+
void Lock() EXCLUSIVE_LOCK_FUNCTION();
27+
void Unlock() UNLOCK_FUNCTION();
28+
29+
// for negative capabilities
30+
const ReentrantMutex& operator!() const { return *this; }
31+
};
32+
2433
class SCOPED_LOCKABLE MutexLock {
2534
public:
2635
MutexLock(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);
@@ -89,6 +98,29 @@ class Foo {
8998
}
9099
};
91100

101+
class Reentrant {
102+
ReentrantMutex mu;
103+
104+
public:
105+
void acquire() {
106+
mu.Lock(); // no warning -- reentrant mutex
107+
mu.Unlock();
108+
}
109+
110+
void requireNegative() EXCLUSIVE_LOCKS_REQUIRED(!mu) { // warning?
111+
mu.Lock();
112+
mu.Unlock();
113+
}
114+
115+
void callRequireNegative() {
116+
requireNegative(); // expected-warning{{calling function 'requireNegative' requires negative capability '!mu'}}
117+
}
118+
119+
void callHaveNegative() EXCLUSIVE_LOCKS_REQUIRED(!mu) {
120+
requireNegative();
121+
}
122+
};
123+
92124
} // end namespace SimpleTest
93125

94126
Mutex globalMutex;

0 commit comments

Comments
 (0)