Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[webkit.UncountedLambdaCapturesChecker] Treat every argument of std::ranges functions as noescape. #138995

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

rniwa
Copy link
Contributor

@rniwa rniwa commented May 7, 2025

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.

…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.
@rniwa rniwa requested a review from t-rasmud May 7, 2025 23:57
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:static analyzer labels May 7, 2025
@llvmbot
Copy link
Member

llvmbot commented May 7, 2025

@llvm/pr-subscribers-clang-static-analyzer-1

@llvm/pr-subscribers-clang

Author: Ryosuke Niwa (rniwa)

Changes

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.


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

2 Files Affected:

  • (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp (+11-3)
  • (modified) clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp (+33)
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

Copy link

github-actions bot commented May 7, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Contributor

@t-rasmud t-rasmud left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@rniwa
Copy link
Contributor Author

rniwa commented May 10, 2025

Thanks for the review!

@rniwa rniwa merged commit 436504c into llvm:main May 10, 2025
11 checks passed
@rniwa rniwa deleted the webkit-treat-arguments-of-std-ranges-as-noescape branch May 10, 2025 00:44
rniwa added a commit to rniwa/llvm-project that referenced this pull request May 10, 2025
…ranges functions as noescape. (llvm#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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:static analyzer clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants