https://github.com/gamesh411 updated https://github.com/llvm/llvm-project/pull/168338
From b5a831cca3113e3dfeead21438bdfa1803094d7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Endre=20F=C3=BCl=C3=B6p?= <[email protected]> Date: Fri, 14 Nov 2025 11:46:38 +0100 Subject: [PATCH 1/2] [clang][analyzer] Add defer_lock_t modelling to BlockInCriticalSectionChecker --- .../BlockInCriticalSectionChecker.cpp | 20 ++++++++++++++++++- .../Analysis/block-in-critical-section.cpp | 9 +++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp index 68bee710e5ce5..99137e038811d 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp @@ -115,7 +115,25 @@ class RAIIMutexDescriptor { return false; const IdentifierInfo *II = cast<CXXRecordDecl>(C->getDecl()->getParent())->getIdentifier(); - return II == Guard; + if (II != Guard) + return false; + + // For unique_lock, check if it's constructed with a ctor that takes the tag + // type defer_lock_t. In this case, the lock is not acquired. + if constexpr (std::is_same_v<T, CXXConstructorCall>) { + if (GuardName == "unique_lock" && C->getNumArgs() >= 2) { + const Expr *SecondArg = C->getArgExpr(1); + QualType ArgType = SecondArg->getType().getNonReferenceType(); + QualType UnqualifiedType = ArgType.getUnqualifiedType(); + if (const auto *RD = UnqualifiedType->getAsRecordDecl(); + RD && RD->getName() == "defer_lock_t" && + RD->getDeclContext()->isStdNamespace()) { + return false; + } + } + } + + return true; } public: diff --git a/clang/test/Analysis/block-in-critical-section.cpp b/clang/test/Analysis/block-in-critical-section.cpp index ee9a708f231a8..674a09265faa5 100644 --- a/clang/test/Analysis/block-in-critical-section.cpp +++ b/clang/test/Analysis/block-in-critical-section.cpp @@ -16,9 +16,12 @@ struct lock_guard { lock_guard<T>(std::mutex) {} ~lock_guard<T>() {} }; +struct defer_lock_t {}; +constexpr defer_lock_t defer_lock{}; template<typename T> struct unique_lock { unique_lock<T>(std::mutex) {} + unique_lock<T>(std::mutex, defer_lock_t) {} // defer_lock parameter ~unique_lock<T>() {} }; template<typename T> @@ -309,3 +312,9 @@ void testTrylockCurrentlyFalsePositive(pthread_mutex_t *m) { // FIXME: this is a false positive, the lock was not acquired } } + +void testBlockInCriticalSectionUniqueLockWithDeferLock() { + std::mutex g_mutex; + std::unique_lock<std::mutex> lock(g_mutex, std::defer_lock); + sleep(1); // no-warning +} From e9613ff2bc4cd1b157d3d8a4a8e63c0af1626afb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Endre=20F=C3=BCl=C3=B6p?= <[email protected]> Date: Wed, 19 Nov 2025 14:22:00 +0100 Subject: [PATCH 2/2] Update clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Donát Nagy <[email protected]> --- .../StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp index 99137e038811d..f6cfa24645546 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp @@ -124,8 +124,7 @@ class RAIIMutexDescriptor { if (GuardName == "unique_lock" && C->getNumArgs() >= 2) { const Expr *SecondArg = C->getArgExpr(1); QualType ArgType = SecondArg->getType().getNonReferenceType(); - QualType UnqualifiedType = ArgType.getUnqualifiedType(); - if (const auto *RD = UnqualifiedType->getAsRecordDecl(); + if (const auto *RD = ArgType->getAsRecordDecl(); RD && RD->getName() == "defer_lock_t" && RD->getDeclContext()->isStdNamespace()) { return false; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
