diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp index 033eb8cc299b0..50532abfb33ce 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);