Skip to content

Commit e6af544

Browse files
committed
[clang][ThreadSafety] Handle mutex scope
Before emitting warning about locks being held at the end of function scope check if the underlying mutex is function scoped or not.
1 parent a549e73 commit e6af544

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed

clang/lib/Analysis/ThreadSafety.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2443,6 +2443,22 @@ void ThreadSafetyAnalyzer::intersectAndWarn(FactSet &EntrySet,
24432443
if (join(FactMan[*EntryIt], ExitFact, JoinLoc, EntryLEK))
24442444
*EntryIt = Fact;
24452445
} else if (!ExitFact.managed() || EntryLEK == LEK_LockedAtEndOfFunction) {
2446+
if (EntryLEK == LEK_LockedAtEndOfFunction) {
2447+
const til::SExpr *Sexp = ExitFact.sexpr();
2448+
const VarDecl *Var = nullptr;
2449+
2450+
if (const auto *Proj = dyn_cast<til::Project>(Sexp)) {
2451+
if (const auto *Base = dyn_cast<til::LiteralPtr>(Proj->record()))
2452+
Var = dyn_cast_or_null<VarDecl>(Base->clangDecl());
2453+
} else if (const auto *LP = dyn_cast<til::LiteralPtr>(Sexp)) {
2454+
Var = dyn_cast_or_null<VarDecl>(LP->clangDecl());
2455+
}
2456+
2457+
if (Var && Var->getStorageDuration() == SD_Automatic &&
2458+
Var->getDeclContext() == CurrentFunction) {
2459+
continue;
2460+
}
2461+
}
24462462
ExitFact.handleRemovalFromIntersection(ExitSet, FactMan, JoinLoc,
24472463
EntryLEK, Handler);
24482464
}

libcxx/test/extensions/clang/thread/thread.mutex/lock.verify.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,9 @@ void f3() {
4545
expected-warning {{mutex 'm2' is still held at the end of function}} \
4646
expected-warning {{mutex 'm3' is still held at the end of function}}
4747
#endif
48+
49+
void f4() {
50+
std::mutex local_m0;
51+
std::mutex local_m1;
52+
std::lock(local_m0, local_m1);
53+
}

0 commit comments

Comments
 (0)