[clang] [llvm] [Clang] Improve type safety in RAIIMemberMutexDescriptor (PR #204338)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 17 04:31:27 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-static-analyzer-1
Author: JasonHonKL
<details>
<summary>Changes</summary>
Add explicit cast<CXXMethodDecl>() when obtaining the method declaration from CXXMemberCall in RAIIMemberMutexDescriptor::matches().
This change:
- Improves type safety by making pointer conversions explicit
- Provides debug build validation through LLVM's cast<T>() assertion
- Has zero runtime overhead (optimized away in release builds)
- Aligns with LLVM coding style for known-valid type conversions
The RAIIMemberMutexDescriptor class handles explicit lock()/unlock() member calls on RAII mutex wrappers like std::unique_lock, complementing the constructor/destructor handling in RAIIMutexDescriptor. This ensures the BlockInCriticalSection checker correctly tracks lock state when manual lock/unlock methods are used.
Fixes #<!-- -->204304
---
Full diff: https://github.com/llvm/llvm-project/pull/204338.diff
1 Files Affected:
- (modified) clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp (+51-3)
``````````diff
diff --git a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
index 03c576270797b..3d0b27af79763 100644
--- a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
@@ -157,9 +157,55 @@ class RAIIMutexDescriptor {
}
};
+class RAIIMemberMutexDescriptor {
+ mutable const IdentifierInfo *WrapperType{};
+ mutable bool IdentifierInitialized{};
+ mutable llvm::SmallString<32> WrapperTypeName{};
+
+ void initIdentifierInfo(const CallEvent &Call) const {
+ if (!IdentifierInitialized) {
+ const auto &ASTCtx = Call.getASTContext();
+ WrapperType = &ASTCtx.Idents.get(WrapperTypeName);
+ IdentifierInitialized = true;
+ }
+ }
+
+public:
+ RAIIMemberMutexDescriptor(StringRef WrapperTypeName)
+ : WrapperTypeName(WrapperTypeName) {}
+
+ [[nodiscard]] bool matches(const CallEvent &Call, bool IsLock) const {
+ initIdentifierInfo(Call);
+
+ const auto *MemCall = dyn_cast<CXXMemberCall>(&Call);
+ if (!MemCall)
+ return false;
+
+ const CXXMethodDecl *Method = cast<CXXMethodDecl>(MemCall->getDecl());
+ const CXXRecordDecl *ClassDecl = Method->getParent();
+ const IdentifierInfo *ClassName = ClassDecl->getIdentifier();
+
+ if (ClassName != WrapperType)
+ return false;
+
+ const IdentifierInfo *MethodName = Method->getIdentifier();
+ if (!MethodName)
+ return false;
+
+ if (IsLock)
+ return MethodName->isStr("lock");
+ else
+ return MethodName->isStr("unlock");
+ }
+
+ [[nodiscard]] const MemRegion *getRegion(const CallEvent &Call, bool) const {
+ return cast<CXXMemberCall>(Call).getCXXThisVal().getAsRegion();
+ }
+};
+
using MutexDescriptor =
std::variant<FirstArgMutexDescriptor, MemberMutexDescriptor,
- RAIIMutexDescriptor>;
+ RAIIMutexDescriptor, RAIIMemberMutexDescriptor>;
class SuppressNonBlockingStreams : public BugReporterVisitor {
private:
@@ -214,7 +260,7 @@ class SuppressNonBlockingStreams : public BugReporterVisitor {
class BlockInCriticalSectionChecker : public Checker<check::PostCall> {
private:
- const std::array<MutexDescriptor, 9> MutexDescriptors{
+ const std::array<MutexDescriptor, 11> MutexDescriptors{
// NOTE: There are standard library implementations where some methods
// of `std::mutex` are inherited from an implementation detail base
// class, and those aren't matched by the name specification {"std",
@@ -239,7 +285,9 @@ class BlockInCriticalSectionChecker : public Checker<check::PostCall> {
{CDM::CLibrary, {"mtx_unlock"}, 1}),
RAIIMutexDescriptor("lock_guard"),
RAIIMutexDescriptor("unique_lock"),
- RAIIMutexDescriptor("scoped_lock")};
+ RAIIMemberMutexDescriptor("unique_lock"),
+ RAIIMutexDescriptor("scoped_lock"),
+ RAIIMemberMutexDescriptor("scoped_lock")};
const CallDescriptionSet BlockingFunctions{{CDM::CLibrary, {"sleep"}},
{CDM::CLibrary, {"getc"}},
``````````
</details>
https://github.com/llvm/llvm-project/pull/204338
More information about the cfe-commits
mailing list