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] [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
+}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to