From 07c97deac16a07e9e5e188d19dda4d2544114611 Mon Sep 17 00:00:00 2001 From: Ryosuke Niwa Date: Fri, 10 Oct 2025 23:43:46 -0700 Subject: [PATCH 1/3] [webkit.UncountedLambdaCapturesChecker] Ignore a lambda which gets called immediately Recognize more ways in which a lambda can be declared and called immediately. --- .../WebKit/RawPtrRefLambdaCapturesChecker.cpp | 10 ++++++++++ .../WebKit/uncounted-lambda-captures.cpp | 17 +++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp index 033eb8cc299b0..6b3a4a77e30c7 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp @@ -253,6 +253,16 @@ class RawPtrRefLambdaCapturesChecker auto *Callee = CE->getCallee(); if (!Callee) return; + Callee = Callee->IgnoreParenCasts(); + if (auto *MTE = dyn_cast(Callee)) + Callee = MTE->getSubExpr(); + if (!Callee) + return; + Callee = Callee->IgnoreParenCasts(); + if (auto* L = dyn_cast_or_null(Callee)) { + LambdasToIgnore.insert(L); // Calling a lambda upon creation is safe. + return; + } auto *DRE = dyn_cast(Callee->IgnoreParenCasts()); if (!DRE) return; diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp index a4ad741182f56..7a8a433e9a7ca 100644 --- a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp @@ -439,6 +439,23 @@ void capture_copy_in_lambda(CheckedObj& checked) { }); } +struct TemplateFunctionCallsLambda { + void ref() const; + void deref() const; + + RefCountable* obj(); + + template + RefPtr method(T* t) { + auto ret = ([&]() -> RefPtr { + if constexpr (T::isEncodable) + return t; + return obj() ? t : nullptr; + })(); + return ret; + } +}; + class Iterator { public: Iterator(void* array, unsigned long sizeOfElement, unsigned int index); From 05f8c56be6e8e01d50d458a11d103deb889b1451 Mon Sep 17 00:00:00 2001 From: Ryosuke Niwa Date: Fri, 10 Oct 2025 23:54:26 -0700 Subject: [PATCH 2/3] Fix formatting --- .../Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp index 6b3a4a77e30c7..50532abfb33ce 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp @@ -259,7 +259,7 @@ class RawPtrRefLambdaCapturesChecker if (!Callee) return; Callee = Callee->IgnoreParenCasts(); - if (auto* L = dyn_cast_or_null(Callee)) { + if (auto *L = dyn_cast_or_null(Callee)) { LambdasToIgnore.insert(L); // Calling a lambda upon creation is safe. return; } From 3cdaeea14fe095662eeb20c5e5d5f117c57061d6 Mon Sep 17 00:00:00 2001 From: Ryosuke Niwa Date: Thu, 23 Oct 2025 17:25:38 -0700 Subject: [PATCH 3/3] Move the null check and IgnoreParenCasts on Callee to inside the if statement for MaterializeTemporaryExpr. --- .../Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp index 50532abfb33ce..0291ad56e9537 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp @@ -254,11 +254,12 @@ class RawPtrRefLambdaCapturesChecker if (!Callee) return; Callee = Callee->IgnoreParenCasts(); - if (auto *MTE = dyn_cast(Callee)) + if (auto *MTE = dyn_cast(Callee)) { Callee = MTE->getSubExpr(); - if (!Callee) - return; - Callee = Callee->IgnoreParenCasts(); + if (!Callee) + return; + Callee = Callee->IgnoreParenCasts(); + } if (auto *L = dyn_cast_or_null(Callee)) { LambdasToIgnore.insert(L); // Calling a lambda upon creation is safe. return;