Author: Endre Fülöp
Date: 2025-11-19T15:55:44+01:00
New Revision: b11b7b333ddb90db42dfd2d5003e3a51c3a7c38a

URL: 
https://github.com/llvm/llvm-project/commit/b11b7b333ddb90db42dfd2d5003e3a51c3a7c38a
DIFF: 
https://github.com/llvm/llvm-project/commit/b11b7b333ddb90db42dfd2d5003e3a51c3a7c38a.diff

LOG: [clang][analyzer] Add defer_lock_t modelling to 
BlockInCriticalSectionChecker (#168338)

Fixes #166573

---------

Co-authored-by: Donát Nagy <[email protected]>
Co-authored-by: Alan Li <[email protected]>

Added: 
    

Modified: 
    clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
    clang/test/Analysis/block-in-critical-section.cpp

Removed: 
    


################################################################################
diff  --git 
a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
index 68bee710e5ce5..2db5310271e1d 100644
--- a/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
@@ -115,7 +115,23 @@ 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();
+        if (const auto *RD = ArgType->getAsRecordDecl();
+            RD && RD->getName() == "defer_lock_t" && RD->isInStdNamespace()) {
+          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