[clang] da6ac95 - [webkit.UncountedLambdaCapturesChecker] Support [[clang::noescape]] on a constructor (#126869)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 14 13:49:35 PST 2025
Author: Ryosuke Niwa
Date: 2025-02-14T13:49:31-08:00
New Revision: da6ac9564bf31e8b063b73e9b2fb7fc67edd5d55
URL: https://github.com/llvm/llvm-project/commit/da6ac9564bf31e8b063b73e9b2fb7fc67edd5d55
DIFF: https://github.com/llvm/llvm-project/commit/da6ac9564bf31e8b063b73e9b2fb7fc67edd5d55.diff
LOG: [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.
Added:
Modified:
clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp
Removed:
################################################################################
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
index a56f48c83c660..972364a855eb4 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp
@@ -41,6 +41,7 @@ class UncountedLambdaCapturesChecker
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 @@ class UncountedLambdaCapturesChecker
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 @@ class UncountedLambdaCapturesChecker
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 @@ class UncountedLambdaCapturesChecker
TempExpr = dyn_cast<CXXBindTemporaryExpr>(Init->IgnoreParenCasts());
if (!TempExpr)
return nullptr;
+ ConstructToIgnore.insert(CE);
return dyn_cast_or_null<LambdaExpr>(TempExpr->getSubExpr());
}
diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp
index 4f4a960282253..62a8245db99b9 100644
--- a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp
+++ b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp
@@ -298,7 +298,11 @@ struct RefCountableWithLambdaCapturingThis {
callLambda([&]() -> RefPtr<RefCountable> {
return obj->next();
});
+ WTF::HashMap<int, RefPtr<RefCountable>> anotherMap([&] {
+ return obj->next();
+ });
}
+
};
struct NonRefCountableWithLambdaCapturingThis {
More information about the cfe-commits
mailing list