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 { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits