Skip to content

Commit 744272e

Browse files
committed
Fix false negative for field regions
1 parent 013a6d1 commit 744272e

File tree

2 files changed

+13
-5
lines changed

2 files changed

+13
-5
lines changed

clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,13 +241,20 @@ BlockInCriticalSectionChecker::checkDescriptorMatch(const CallEvent &Call,
241241
return std::nullopt;
242242
}
243243

244+
static const MemRegion *skipBaseClassRegion(const MemRegion *Reg) {
245+
while (const auto *BaseClassRegion = dyn_cast<CXXBaseObjectRegion>(Reg)) {
246+
Reg = BaseClassRegion->getSuperRegion();
247+
}
248+
return Reg;
249+
}
250+
244251
static const MemRegion *getRegion(const CallEvent &Call,
245252
const MutexDescriptor &Descriptor,
246253
bool IsLock) {
247254
return std::visit(
248255
[&Call, IsLock](auto &Descr) -> const MemRegion * {
249256
if (const MemRegion *Reg = Descr.getRegion(Call, IsLock))
250-
return Reg->getBaseRegion();
257+
return skipBaseClassRegion(Reg);
251258
return nullptr;
252259
},
253260
Descriptor);

clang/test/Analysis/block-in-critical-section-inheritance.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,12 @@ struct TwoMutexes {
4545
std::mutex m2;
4646
};
4747

48-
void two_mutexes_false_negative(TwoMutexes &tm) {
48+
void two_mutexes_no_false_negative(TwoMutexes &tm) {
4949
tm.m1.lock();
50+
// expected-note@-1 {{Entering critical section here}}
5051
tm.m2.unlock();
51-
// Critical section is associated with tm now so tm.m1 and tm.m2 are
52-
// undistinguishiable
53-
sleep(10); // False-negative
52+
sleep(10);
53+
// expected-warning@-1 {{Call to blocking function 'sleep' inside of critical section}}
54+
// expected-note@-2 {{Call to blocking function 'sleep' inside of critical section}}
5455
tm.m1.unlock();
5556
}

0 commit comments

Comments
 (0)