llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Ryosuke Niwa (rniwa)

<details>
<summary>Changes</summary>

call_once does not store the lambda in heap so consider all its arguments as 
noescape.

---
Full diff: https://github.com/llvm/llvm-project/pull/224492.diff


3 Files Affected:

- (modified) 
clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp 
(+10-3) 
- (modified) clang/test/Analysis/Checkers/WebKit/mock-types.h (+13) 
- (modified) clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp 
(+9) 


``````````diff
diff --git 
a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp
index 43db3065dd068..a07812d3a48d5 100644
--- 
a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp
+++ 
b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp
@@ -244,9 +244,16 @@ class RawPtrRefLambdaCapturesChecker
           // workaround that.
           if (Name == "WTF" && PreviousName == "switchOn")
             return true;
-          // Treat every argument of functions in std::ranges as noescape.
-          if (Name == "std" && PreviousName == "ranges")
-            return true;
+          if (Name == "std") {
+            // Treat every argument of functions in std::ranges as noescape.
+            if (PreviousName == "ranges")
+              return true;
+            // Treat every argument of call_once as noescape even though only
+            // the second argument is lambda since we can't add annotation to
+            // a std function.
+            if (PreviousName == "call_once")
+              return true;
+          }
           PreviousName = Name;
         }
         return false;
diff --git a/clang/test/Analysis/Checkers/WebKit/mock-types.h 
b/clang/test/Analysis/Checkers/WebKit/mock-types.h
index 9ed5ecab88c6e..46818a9642ee3 100644
--- a/clang/test/Analysis/Checkers/WebKit/mock-types.h
+++ b/clang/test/Analysis/Checkers/WebKit/mock-types.h
@@ -63,6 +63,19 @@ class unique_ptr {
   explicit operator bool() const { return !!t; }
 };
 
+struct once_flag {
+  bool did { false };
+};
+
+template<typename CallbackType, typename... Args>
+void call_once(once_flag& flag, CallbackType callback, Args&&... args)
+{
+  if (flag.did)
+    return;
+  flag.did = true;
+  callback(args...);
+}
+
 namespace ranges {
 
 template<typename IteratorType, typename CallbackType>
diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp 
b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp
index d1cc7588ed8d6..27c44af36c2d3 100644
--- a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp
+++ b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp
@@ -386,6 +386,7 @@ class RefCountedObj {
   bool isMatch(int);
 
   void call() const;
+  void callOnce() const;
   void callLambda([[clang::noescape]] const WTF::Function<void ()>& callback) 
const;
   void doSomeWork() const;
 };
@@ -409,6 +410,14 @@ void RefCountedObj::call() const
     callLambda(lambda);
 }
 
+void RefCountedObj::callOnce() const
+{
+  static std::once_flag flag;
+  std::call_once(flag, [&]() {
+    call();
+  });
+}
+
 void scope_exit(RefCountable* obj) {
   auto scope = WTF::makeScopeExit([&] {
     obj->method();

``````````

</details>


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

Reply via email to