Author: Ryosuke Niwa
Date: 2025-05-09T17:44:36-07:00
New Revision: 436504c3b9db3bd11d34ec7457b52bef43fc35cc

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

LOG: [webkit.UncountedLambdaCapturesChecker] Treat every argument of 
std::ranges functions as noescape. (#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.

Added: 
    

Modified: 
    clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp
    clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp

Removed: 
    


################################################################################
diff  --git 
a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp
index 01faa9217982d..c322f377d7ff7 100644
--- 
a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp
+++ 
b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp
@@ -127,13 +127,22 @@ 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


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to