Skip to content

Commit 5a3118e

Browse files
committed
feat: new matchers, fix: comments
1 parent 218fb62 commit 5a3118e

File tree

2 files changed

+29
-55
lines changed

2 files changed

+29
-55
lines changed

clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp

Lines changed: 23 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,20 @@ using namespace clang::ast_matchers;
2222

2323
namespace clang::tidy::modernize {
2424

25+
static bool isLockGuardDecl(const NamedDecl *Decl) {
26+
return Decl->getDeclName().isIdentifier() &&
27+
Decl->getName() == "lock_guard" && Decl->isInStdNamespace();
28+
}
29+
2530
static bool isLockGuard(const QualType &Type) {
2631
if (const auto *Record = Type->getAs<RecordType>())
27-
if (const RecordDecl *Decl = Record->getDecl()) {
28-
assert(Decl->getDeclName().isIdentifier() && "Decl is not identifier");
29-
return Decl->getName() == "lock_guard" && Decl->isInStdNamespace();
30-
}
32+
if (const RecordDecl *Decl = Record->getDecl())
33+
return isLockGuardDecl(Decl);
3134

3235
if (const auto *TemplateSpecType = Type->getAs<TemplateSpecializationType>())
3336
if (const TemplateDecl *Decl =
34-
TemplateSpecType->getTemplateName().getAsTemplateDecl()) {
35-
assert(Decl->getDeclName().isIdentifier() && "Decl is not identifier");
36-
return Decl->getName() == "lock_guard" && Decl->isInStdNamespace();
37-
}
37+
TemplateSpecType->getTemplateName().getAsTemplateDecl())
38+
return isLockGuardDecl(Decl);
3839

3940
return false;
4041
}
@@ -118,48 +119,9 @@ static SourceRange getLockGuardNameRange(const TypeSourceInfo *SourceInfo) {
118119
TemplateLoc.getLAngleLoc().getLocWithOffset(-1));
119120
}
120121

121-
namespace {
122-
123-
AST_MATCHER_P(CompoundStmt, hasMultiple, ast_matchers::internal::Matcher<Stmt>,
124-
InnerMatcher) {
125-
size_t Count = 0;
126-
127-
for (const Stmt *Stmt : Node.body())
128-
if (InnerMatcher.matches(*Stmt, Finder, Builder))
129-
Count++;
130-
131-
return Count > 1;
132-
}
133-
134-
AST_MATCHER_P(CompoundStmt, hasSingle, ast_matchers::internal::Matcher<Stmt>,
135-
InnerMatcher) {
136-
size_t Count = 0;
137-
ast_matchers::internal::BoundNodesTreeBuilder Result;
138-
139-
for (const Stmt *Stmt : Node.body()) {
140-
ast_matchers::internal::BoundNodesTreeBuilder TB(*Builder);
141-
if (InnerMatcher.matches(*Stmt, Finder, &TB)) {
142-
Count++;
143-
if (Count == 1)
144-
Result.addMatch(TB);
145-
}
146-
}
147-
148-
if (Count > 1) {
149-
Builder->removeBindings(
150-
[](const ast_matchers::internal::BoundNodesMap &) { return true; });
151-
return false;
152-
}
153-
154-
*Builder = std::move(Result);
155-
return true;
156-
}
157-
158-
const StringRef UseScopedLockMessage =
122+
const static StringRef UseScopedLockMessage =
159123
"use 'std::scoped_lock' instead of 'std::lock_guard'";
160124

161-
} // namespace
162-
163125
UseScopedLockCheck::UseScopedLockCheck(StringRef Name,
164126
ClangTidyContext *Context)
165127
: ClangTidyCheck(Name, Context),
@@ -187,14 +149,19 @@ void UseScopedLockCheck::registerMatchers(MatchFinder *Finder) {
187149
Finder->addMatcher(
188150
compoundStmt(
189151
unless(isExpansionInSystemHeader()),
190-
hasSingle(declStmt(has(LockVarDecl.bind("lock-decl-single"))))),
152+
has(declStmt(has(LockVarDecl)).bind("lock-decl-single")),
153+
unless(has(declStmt(unless(equalsBoundNode("lock-decl-single")),
154+
has(LockVarDecl))))),
191155
this);
192156
}
193157

194-
Finder->addMatcher(compoundStmt(unless(isExpansionInSystemHeader()),
195-
hasMultiple(declStmt(has(LockVarDecl))))
196-
.bind("block-multiple"),
197-
this);
158+
Finder->addMatcher(
159+
compoundStmt(unless(isExpansionInSystemHeader()),
160+
has(declStmt(has(LockVarDecl)).bind("lock-decl-multiple")),
161+
has(declStmt(unless(equalsBoundNode("lock-decl-multiple")),
162+
has(LockVarDecl))))
163+
.bind("block-multiple"),
164+
this);
198165

199166
if (WarnOnUsingAndTypedef) {
200167
// Match 'typedef std::lock_guard<std::mutex> Lock'
@@ -222,8 +189,9 @@ void UseScopedLockCheck::registerMatchers(MatchFinder *Finder) {
222189
}
223190

224191
void UseScopedLockCheck::check(const MatchFinder::MatchResult &Result) {
225-
if (const auto *Decl = Result.Nodes.getNodeAs<VarDecl>("lock-decl-single")) {
226-
diagOnSingleLock(Decl, Result);
192+
if (const auto *DS = Result.Nodes.getNodeAs<DeclStmt>("lock-decl-single")) {
193+
llvm::SmallVector<const VarDecl *> Decls = getLockGuardsFromDecl(DS);
194+
diagOnMultipleLocks({Decls}, Result);
227195
return;
228196
}
229197

clang-tools-extra/test/clang-tidy/checkers/modernize/use-scoped-lock.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ void Positive() {
2323
// CHECK-MESSAGES: :[[@LINE-2]]:33: note: additional 'std::lock_guard' declared here
2424
}
2525

26+
{
27+
std::lock_guard<std::mutex> l1(m), l2(m);
28+
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use single 'std::scoped_lock' instead of multiple 'std::lock_guard'
29+
// CHECK-MESSAGES: :[[@LINE-2]]:40: note: additional 'std::lock_guard' declared here
30+
}
31+
2632
{
2733
std::lock_guard<std::mutex> l1(m), l2(m), l3(m);
2834
std::lock_guard<std::mutex> l4(m);

0 commit comments

Comments
 (0)