[webkit.UncountedLambdaCapturesChecker] Support [[clang::noescape]] on a constructor (#126869)

Added the support for annotating a constructor's argument with
[[clang::noescape]].

We explicitly ignore CXXConstructExpr which is visited as a part of
CallExpr so that construction of closures like Function,
CompletionHandler, etc... don't result in a warning.
This commit is contained in:
Ryosuke Niwa
2025-02-14 13:49:31 -08:00
committed by GitHub
parent 18f60bc335
commit da6ac9564b
2 changed files with 29 additions and 1 deletions

View File

@@ -41,6 +41,7 @@ public:
const UncountedLambdaCapturesChecker *Checker;
llvm::DenseSet<const DeclRefExpr *> DeclRefExprsToIgnore;
llvm::DenseSet<const LambdaExpr *> LambdasToIgnore;
llvm::DenseSet<const CXXConstructExpr *> ConstructToIgnore;
QualType ClsType;
explicit LocalVisitor(const UncountedLambdaCapturesChecker *Checker)
@@ -106,6 +107,26 @@ public:
return safeGetName(NsDecl) == "WTF" && safeGetName(Decl) == "switchOn";
}
bool VisitCXXConstructExpr(CXXConstructExpr *CE) override {
if (ConstructToIgnore.contains(CE))
return true;
if (auto *Callee = CE->getConstructor()) {
unsigned ArgIndex = 0;
for (auto *Param : Callee->parameters()) {
if (ArgIndex >= CE->getNumArgs())
return true;
auto *Arg = CE->getArg(ArgIndex)->IgnoreParenCasts();
if (auto *L = findLambdaInArg(Arg)) {
LambdasToIgnore.insert(L);
if (!Param->hasAttr<NoEscapeAttr>())
Checker->visitLambdaExpr(L, shouldCheckThis());
}
++ArgIndex;
}
}
return true;
}
bool VisitCallExpr(CallExpr *CE) override {
checkCalleeLambda(CE);
if (auto *Callee = CE->getDirectCallee()) {
@@ -143,8 +164,10 @@ public:
auto *CtorArg = CE->getArg(0)->IgnoreParenCasts();
if (!CtorArg)
return nullptr;
if (auto *Lambda = dyn_cast<LambdaExpr>(CtorArg))
if (auto *Lambda = dyn_cast<LambdaExpr>(CtorArg)) {
ConstructToIgnore.insert(CE);
return Lambda;
}
auto *DRE = dyn_cast<DeclRefExpr>(CtorArg);
if (!DRE)
return nullptr;
@@ -157,6 +180,7 @@ public:
TempExpr = dyn_cast<CXXBindTemporaryExpr>(Init->IgnoreParenCasts());
if (!TempExpr)
return nullptr;
ConstructToIgnore.insert(CE);
return dyn_cast_or_null<LambdaExpr>(TempExpr->getSubExpr());
}

View File

@@ -298,7 +298,11 @@ struct RefCountableWithLambdaCapturingThis {
callLambda([&]() -> RefPtr<RefCountable> {
return obj->next();
});
WTF::HashMap<int, RefPtr<RefCountable>> anotherMap([&] {
return obj->next();
});
}
};
struct NonRefCountableWithLambdaCapturingThis {