================ @@ -45,32 +52,118 @@ class UncountedLambdaCapturesChecker bool shouldVisitTemplateInstantiations() const { return true; } bool shouldVisitImplicitCode() const { return false; } - bool VisitLambdaExpr(LambdaExpr *L) { - Checker->visitLambdaExpr(L); + bool TraverseCXXMethodDecl(CXXMethodDecl *CXXMD) { + llvm::SaveAndRestore SavedDecl(ClsType); + ClsType = CXXMD->getThisType(); + return Base::TraverseDecl(CXXMD); + } + + bool shouldCheckThis() { + auto result = !ClsType.isNull() ? isUnsafePtr(ClsType) : std::nullopt; + return result && *result; + } + + bool VisitDeclRefExpr(DeclRefExpr *DRE) { + if (DeclRefExprsToIgnore.contains(DRE)) + return true; + auto *VD = dyn_cast_or_null<VarDecl>(DRE->getDecl()); + if (!VD) + return true; + auto *Init = VD->getInit(); + if (!Init) + return true; + auto *L = dyn_cast_or_null<LambdaExpr>(Init->IgnoreParenCasts()); + if (!L) + return true; + Checker->visitLambdaExpr(L, shouldCheckThis()); return true; } + + // WTF::switchOn(T, F... f) is a variadic template function and couldn't + // be annotated with NOESCAPE. We hard code it here to workaround that. + bool shouldTreatAllArgAsNoEscape(FunctionDecl *Decl) { + auto *NsDecl = Decl->getParent(); + if (!NsDecl || !isa<NamespaceDecl>(NsDecl)) + return false; + return safeGetName(NsDecl) == "WTF" && safeGetName(Decl) == "switchOn"; + } + + bool VisitCallExpr(CallExpr *CE) { + checkCalleeLambda(CE); + if (auto *Callee = CE->getDirectCallee()) { + bool TreatAllArgsAsNoEscape = shouldTreatAllArgAsNoEscape(Callee); + unsigned ArgIndex = 0; + for (auto *Param : Callee->parameters()) { + if (ArgIndex >= CE->getNumArgs()) + break; ---------------- rniwa wrote:
Sure, we can do that. https://github.com/llvm/llvm-project/pull/114897 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits