[clang] [webkit.UncountedLambdaCapturesChecker] Treat every argument of std::ranges functions as noescape. (PR #138995)
Ryosuke Niwa via cfe-commits
cfe-commits at lists.llvm.org
Wed May 7 16:57:16 PDT 2025
https://github.com/rniwa created https://github.com/llvm/llvm-project/pull/138995
Functions in std::ranges namespace does not store the lambada passed-in as an arugment in heap so treat such an argument as if it has [[noescape]] in the WebKit lambda capture checker so that we don't emit warnings for capturing raw pointers or references to smart-pointer capable objects.
>From d4b5f004e2d91e8d821e20bee6fcb43b87701b9d Mon Sep 17 00:00:00 2001
From: Ryosuke Niwa <rniwa at webkit.org>
Date: Wed, 7 May 2025 16:53:35 -0700
Subject: [PATCH] [webkit.UncountedLambdaCapturesChecker] Treat every argument
of std::ranges functions as noescape.
Functions in std::ranges namespace does not store the lambada passed-in as an arugment in heap
so treat such an argument as if it has [[noescape]] in the WebKit lambda capture checker so that
we don't emit warnings for capturing raw pointers or references to smart-pointer capable objects.
---
.../WebKit/RawPtrRefLambdaCapturesChecker.cpp | 14 ++++++--
.../WebKit/uncounted-lambda-captures.cpp | 33 +++++++++++++++++++
2 files changed, 44 insertions(+), 3 deletions(-)
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp
index 01faa9217982d..d3b8d8b6995bf 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp
@@ -127,13 +127,21 @@ class RawPtrRefLambdaCapturesChecker
return true;
}
- // WTF::switchOn(T, F... f) is a variadic template function and couldn't
- // be annotated with NOESCAPE. We hard code it here to workaround that.
bool shouldTreatAllArgAsNoEscape(FunctionDecl *Decl) {
auto *NsDecl = Decl->getParent();
if (!NsDecl || !isa<NamespaceDecl>(NsDecl))
return false;
- return safeGetName(NsDecl) == "WTF" && safeGetName(Decl) == "switchOn";
+ // WTF::switchOn(T, F... f) is a variadic template function and couldn't
+ // be annotated with NOESCAPE. We hard code it here to workaround that.
+ if (safeGetName(NsDecl) == "WTF" && safeGetName(Decl) == "switchOn")
+ return true;
+ // Treat every argument of functions in std::ranges as noescape.
+ if (safeGetName(NsDecl) == "ranges") {
+ if (auto *OuterDecl = NsDecl->getParent(); OuterDecl &&
+ isa<NamespaceDecl>(OuterDecl) && safeGetName(OuterDecl) == "std")
+ return true;
+ }
+ return false;
}
bool VisitCXXConstructExpr(CXXConstructExpr *CE) override {
diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp
index 6b7593a821c64..3079f8e833fcd 100644
--- a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp
+++ b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp
@@ -9,6 +9,16 @@ T&& move(T& t) {
return static_cast<T&&>(t);
}
+namespace ranges {
+
+template<typename IteratorType, typename CallbackType>
+void for_each(IteratorType first, IteratorType last, CallbackType callback) {
+ for (auto it = first; !(it == last); ++it)
+ callback(*it);
+}
+
+}
+
}
namespace WTF {
@@ -416,3 +426,26 @@ void capture_copy_in_lambda(CheckedObj& checked) {
ptr->method();
});
}
+
+class Iterator {
+public:
+ Iterator(void* array, unsigned long sizeOfElement, unsigned int index);
+ Iterator(const Iterator&);
+ Iterator& operator=(const Iterator&);
+ bool operator==(const Iterator&);
+
+ Iterator& operator++();
+ void* operator*();
+
+private:
+ void* current { nullptr };
+ unsigned long sizeOfElement { 0 };
+};
+
+void ranges_for_each(RefCountable* obj) {
+ int array[] = { 1, 2, 3, 4, 5 };
+ std::ranges::for_each(Iterator(array, sizeof(*array), 0), Iterator(array, sizeof(*array), 5), [&](void* item) {
+ obj->method();
+ ++(*static_cast<unsigned*>(item));
+ });
+}
\ No newline at end of file
More information about the cfe-commits
mailing list