================
@@ -0,0 +1,333 @@
+// RUN: %check_clang_tidy -std=c++17-or-later %s modernize-use-scoped-lock %t 
-- -- -fno-delayed-template-parsing
+
+namespace std {
+
+struct mutex {
+  void lock() {}
+  void unlock() {}
+};
+
+template<class Lockable1, class Lockable2, class... LockableN >
+void lock(Lockable1& lock1, Lockable2& lock2, LockableN&... lockn );
+
+struct adopt_lock_t { };
+std::adopt_lock_t adopt_lock {};
+
+template <typename Mutex>
+struct lock_guard {
+  lock_guard(Mutex &m) { }
+  lock_guard(Mutex &m, std::adopt_lock_t t) {}
+  lock_guard( const lock_guard& ) = delete;
+};
+
+template <typename... MutexTypes>
+struct scoped_lock {
+  scoped_lock(MutexTypes&... m) {}
+  scoped_lock(std::adopt_lock_t t, MutexTypes&... m) {}
+};
+
+} // namespace std
+
+
+void Positive() {
+  std::mutex m;
+  {
+    std::lock_guard<std::mutex> l(m);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead 
of 'std::lock_guard'
+    // CHECK-FIXES: std::scoped_lock l(m);
+  }
+
+  {
+    std::lock_guard<std::mutex> l(m, std::adopt_lock);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead 
of 'std::lock_guard'
+    // CHECK-FIXES: std::scoped_lock l(std::adopt_lock, m);
+  }
+
+  {
+    std::lock_guard<std::mutex> l1(m);
+    std::lock_guard<std::mutex> l2(m);
+    // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use single 'std::scoped_lock' 
instead of multiple 'std::lock_guard'
+    // CHECK-MESSAGES: :[[@LINE-2]]:33: note: additional 'std::lock_guard' 
declared here
+  }
+
+  {
+    std::lock_guard<std::mutex> l1(m), l2(m), l3(m);
+    std::lock_guard<std::mutex> l4(m);
+    // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use single 'std::scoped_lock' 
instead of multiple 'std::lock_guard'
+    // CHECK-MESSAGES: :[[@LINE-3]]:40: note: additional 'std::lock_guard' 
declared here
+    // CHECK-MESSAGES: :[[@LINE-4]]:47: note: additional 'std::lock_guard' 
declared here
+    // CHECK-MESSAGES: :[[@LINE-4]]:33: note: additional 'std::lock_guard' 
declared here
+  }
+  
+  { 
+    std::lock(m, m);
+    std::lock_guard<std::mutex> l1(m, std::adopt_lock);
+    std::lock_guard<std::mutex> l2(m, std::adopt_lock);
+    // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use single 'std::scoped_lock' 
instead of multiple 'std::lock_guard'
+    // CHECK-MESSAGES: :[[@LINE-2]]:33: note: additional 'std::lock_guard' 
declared here
+    int a = 0;
+    std::lock_guard<std::mutex> l3(m);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead 
of 'std::lock_guard'
+    // CHECK-FIXES: std::scoped_lock l3(m);
+    int b = 0;
+    std::lock_guard<std::mutex> l4(m, std::adopt_lock);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead 
of 'std::lock_guard'
+    // CHECK-FIXES: std::scoped_lock l4(std::adopt_lock, m);
+  } 
+}
+
+
+std::mutex p_m1;
+void PositiveShortFunction() {
+  std::lock_guard<std::mutex> l(p_m1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'std::scoped_lock' instead 
of 'std::lock_guard'
+  // CHECK-FIXES: std::scoped_lock l(p_m1);
+}
+
+
+void PositiveNested() {
+  std::mutex m1;
+  if (true) {
+    std::lock_guard<std::mutex> l(m1);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead 
of 'std::lock_guard'
+    // CHECK-FIXES: std::scoped_lock l(m1);
+    {
+      std::lock_guard<std::mutex> l2(m1);
+      // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use 'std::scoped_lock' 
instead of 'std::lock_guard'
+      // CHECK-FIXES: std::scoped_lock l2(m1);
+      {
+        std::lock_guard<std::mutex> l3(m1);
+        std::lock_guard<std::mutex> l4(m1);
+        // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: use single 
'std::scoped_lock' instead of multiple 'std::lock_guard'
+        // CHECK-MESSAGES: :[[@LINE-2]]:37: note: additional 'std::lock_guard' 
declared here
+      }
+      {
+        std::lock_guard<std::mutex> l2(m1);
+        // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use 'std::scoped_lock' 
instead of 'std::lock_guard'
+        // CHECK-FIXES: std::scoped_lock l2(m1);
+      }
+    }
+  }
+  std::lock_guard<std::mutex> l(m1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'std::scoped_lock' instead 
of 'std::lock_guard'
+  // CHECK-FIXES: std::scoped_lock l(m1);
+}
+
+
+void PositiveInsideArg(std::mutex &m1, std::mutex &m2, std::mutex &m3) {
+  std::lock_guard<std::mutex> l1(m1);
+  std::lock_guard<std::mutex> l2(m2);
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use single 'std::scoped_lock' 
instead of multiple 'std::lock_guard'
+  // CHECK-MESSAGES: :[[@LINE-2]]:31: note: additional 'std::lock_guard' 
declared here
+  int a = 0;
+  std::lock_guard<std::mutex> l3(m3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'std::scoped_lock' instead 
of 'std::lock_guard'
+  // CHECK-FIXES: std::scoped_lock l3(m3);
+}
+
+
+void PositiveInsideConditional() {
+  std::mutex m1;
+  if (true) {
+    std::lock_guard<std::mutex> l1(m1);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead 
of 'std::lock_guard'
+    // CHECK-FIXES: std::scoped_lock l1(m1);
+  } else {
+    std::lock_guard<std::mutex> l1(m1);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead 
of 'std::lock_guard'
+    // CHECK-FIXES: std::scoped_lock l1(m1);
+  }
+
+  while (true) {
+    std::lock_guard<std::mutex> l1(m1);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead 
of 'std::lock_guard'
+    // CHECK-FIXES: std::scoped_lock l1(m1);
+  }
+
+  for (int i = 0; i < 10; ++i) {
+    std::lock_guard<std::mutex> l1(m1);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead 
of 'std::lock_guard'
+    // CHECK-FIXES: std::scoped_lock l1(m1);
+  }
+}
+
+
+template <typename T>
+void PositiveTemplated() {
+  std::mutex m1, m2, m3;
+  {
+    std::lock_guard<std::mutex> l(m1);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead 
of 'std::lock_guard'
+    // CHECK-FIXES: std::scoped_lock l(m1);
+  }
+
+  {
+    std::lock_guard<std::mutex> l1(m1);
+    std::lock_guard<std::mutex> l2(m2);
+    // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use single 'std::scoped_lock' 
instead of multiple 'std::lock_guard'
+    // CHECK-MESSAGES: :[[@LINE-2]]:33: note: additional 'std::lock_guard' 
declared here
+  }
+
+  {
+    std::lock(m1, m2);
+    std::lock_guard<std::mutex> l1(m1, std::adopt_lock);
+    std::lock_guard<std::mutex> l2(m2, std::adopt_lock);
+    // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use single 'std::scoped_lock' 
instead of multiple 'std::lock_guard'
+    // CHECK-MESSAGES: :[[@LINE-2]]:33: note: additional 'std::lock_guard' 
declared here
+    int a = 0;
+    std::lock_guard<std::mutex> l3(m3);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead 
of 'std::lock_guard'
+    // CHECK-FIXES: std::scoped_lock l3(m3);
+  }
+}
+
+
+template <typename Mutex>
+void PositiveTemplatedMutex() {
+  Mutex m1, m2, m3;
+  {
+    std::lock_guard<Mutex> l(m1);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead 
of 'std::lock_guard'
+  }
+
+  {
+    std::lock_guard<Mutex> l1(m1);
+    std::lock_guard<Mutex> l2(m2);
+    // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use single 'std::scoped_lock' 
instead of multiple 'std::lock_guard'
+    // CHECK-MESSAGES: :[[@LINE-2]]:28: note: additional 'std::lock_guard' 
declared here
+  }
+
+  {
+    std::lock(m1, m2);
+    std::lock_guard<Mutex> l1(m1, std::adopt_lock);
+    std::lock_guard<Mutex> l2(m2, std::adopt_lock);
+    // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use single 'std::scoped_lock' 
instead of multiple 'std::lock_guard'
+    // CHECK-MESSAGES: :[[@LINE-2]]:28: note: additional 'std::lock_guard' 
declared here
+    int a = 0;
+    std::lock_guard<Mutex> l3(m3);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead 
of 'std::lock_guard'
+  }
+}
+
+
+template <template <typename> typename Lock>
+void NegativeTemplate() {
+  std::mutex m1, m2;
+  {
+    Lock<std::mutex> l(m1);
+  }
+
+  {
+    Lock<std::mutex> l1(m1);
+    Lock<std::mutex> l2(m2);
+  }
+}
+
+void instantiate() {
+  NegativeTemplate<std::lock_guard>();
+}
+
+
+struct PositiveClass {
+  void Positive() {
+    {
+      std::lock_guard<std::mutex> l(m1);
+      // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use 'std::scoped_lock' 
instead of 'std::lock_guard'
+      // CHECK-FIXES: std::scoped_lock l(m1);
+    }
+
+    {
+      std::lock_guard<std::mutex> l1(m1);
+      std::lock_guard<std::mutex> l2(m2);
+      // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: use single 
'std::scoped_lock' instead of multiple 'std::lock_guard'
+      // CHECK-MESSAGES: :[[@LINE-2]]:35: note: additional 'std::lock_guard' 
declared here
+    }
+
+    {
+      std::lock(m1, m2);  
+      std::lock_guard<std::mutex> l1(m1, std::adopt_lock);
+      std::lock_guard<std::mutex> l2(m2, std::adopt_lock);
+      // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: use single 
'std::scoped_lock' instead of multiple 'std::lock_guard'
+      // CHECK-MESSAGES: :[[@LINE-2]]:35: note: additional 'std::lock_guard' 
declared here
+      int a = 0;
+      std::lock_guard<std::mutex> l3(m3);
+      // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use 'std::scoped_lock' 
instead of 'std::lock_guard'
+      // CHECK-FIXES: std::scoped_lock l3(m3);
+    }
+  }
+  
+  std::mutex m1;
+  std::mutex m2;
+  std::mutex m3;
+};
+
+
+template <typename T>
+struct PositiveTemplatedClass {
+  void Positive() {
+    {
+      std::lock_guard<std::mutex> l(m1);
+      // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use 'std::scoped_lock' 
instead of 'std::lock_guard'
+      // CHECK-FIXES: std::scoped_lock l(m1);
+    }
+
+    {
+      std::lock(m1, m2);  
+      std::lock_guard<std::mutex> l1(m1, std::adopt_lock);
+      std::lock_guard<std::mutex> l2(m2, std::adopt_lock);
+      // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: use single 
'std::scoped_lock' instead of multiple 'std::lock_guard'
+      // CHECK-MESSAGES: :[[@LINE-2]]:35: note: additional 'std::lock_guard' 
declared here
+      int a = 0;
+      std::lock_guard<std::mutex> l3(m3);
+      // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use 'std::scoped_lock' 
instead of 'std::lock_guard'
+      // CHECK-FIXES: std::scoped_lock l3(m3);
+    }
+  }
+
+  template <typename... Ts>
+  void TemplatedPositive() {
+    {
+      std::lock_guard<std::mutex> l(m1);
+      // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use 'std::scoped_lock' 
instead of 'std::lock_guard'
+      // CHECK-FIXES: std::scoped_lock l(m1);
+    }
+
+    {
+      std::lock(m1, m2);  
+      std::lock_guard<std::mutex> l1(m1, std::adopt_lock);
+      std::lock_guard<std::mutex> l2(m2, std::adopt_lock);
+      // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: use single 
'std::scoped_lock' instead of multiple 'std::lock_guard'
+      // CHECK-MESSAGES: :[[@LINE-2]]:35: note: additional 'std::lock_guard' 
declared here
+      int a = 0;
+      std::lock_guard<std::mutex> l3(m3);
+      // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use 'std::scoped_lock' 
instead of 'std::lock_guard'
+      // CHECK-FIXES: std::scoped_lock l3(m3);
+    }
+  }
+  
+  std::mutex m1;
+  std::mutex m2;
+  std::mutex m3;
+};
+
+
+template <typename T>
+using Lock = std::lock_guard<T>;
+using LockM = std::lock_guard<std::mutex>;
+typedef std::lock_guard<std::mutex> LockDef;
+
+void NegativeUsingTypedefs() {
----------------
vbvictor wrote:

Added new flag `WarnOnUsingAndTypedef` that warns about usage of 
`std:lock_guard` in `using`, `typedef`

https://github.com/llvm/llvm-project/pull/126434
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to