Skip to content

Commit d5a2638

Browse files
authored
[webkit.UncountedLambdaCapturesChecker] Fix a bug that the checker didn't take the object pointer into account. (#125662)
When a callee is a method call (e.g. calling a lambda), we need to skip the object pointer to match the parameter list with the call arguments. This manifests as a bug that the checker erroneously generate a warning for a lambda capture (L1) which is passed to a no-escape argument of another lambda (L2).
1 parent 31bd82c commit d5a2638

File tree

2 files changed

+13
-2
lines changed

2 files changed

+13
-2
lines changed

clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,10 @@ class UncountedLambdaCapturesChecker
109109
bool VisitCallExpr(CallExpr *CE) override {
110110
checkCalleeLambda(CE);
111111
if (auto *Callee = CE->getDirectCallee()) {
112-
bool TreatAllArgsAsNoEscape = shouldTreatAllArgAsNoEscape(Callee);
113112
unsigned ArgIndex = 0;
113+
if (auto *CXXCallee = dyn_cast<CXXMethodDecl>(Callee))
114+
ArgIndex = CXXCallee->isInstance();
115+
bool TreatAllArgsAsNoEscape = shouldTreatAllArgAsNoEscape(Callee);
114116
for (auto *Param : Callee->parameters()) {
115117
if (ArgIndex >= CE->getNumArgs())
116118
return true;

clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,13 +252,22 @@ struct RefCountableWithLambdaCapturingThis {
252252
call(lambda);
253253
}
254254

255-
void method_captures_this_with_guardian_refPtr() {
255+
void method_captures_this_with_guardian_refptr() {
256256
auto lambda = [this, protectedThis = RefPtr { &*this }]() {
257257
nonTrivial();
258258
};
259259
call(lambda);
260260
}
261261

262+
void forEach(const WTF::Function<void(RefCountable&)>&);
263+
void method_captures_this_with_lambda_with_no_escape() {
264+
auto run = [&]([[clang::noescape]] const WTF::Function<void(RefCountable&)>& func) {
265+
forEach(func);
266+
};
267+
run([&](RefCountable&) {
268+
nonTrivial();
269+
});
270+
}
262271
};
263272

264273
struct NonRefCountableWithLambdaCapturingThis {

0 commit comments

Comments
 (0)