[clang] [webkit.UncountedLambdaCapturesChecker] Treat call_once arguments as noescape (PR #224492)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 17 18:53:10 PDT 2026
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
More information about the cfe-commits
mailing list