================ @@ -11,16 +11,134 @@ #include "PtrTypesSemantics.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/StmtVisitor.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/SetVector.h" #include <optional> using namespace clang; using namespace ento; namespace { + +class DerefAnalysisVisitor + : public ConstStmtVisitor<DerefAnalysisVisitor, bool> { + // Returns true if any of child statements return true. + bool VisitChildren(const Stmt *S) { + for (const Stmt *Child : S->children()) { + if (Child && Visit(Child)) + return true; + } + return false; + } + + bool VisitBody(const Stmt *Body) { + if (!Body) + return false; + + auto [It, IsNew] = VisitedBody.insert(Body); + if (!IsNew) // This body is recursive + return false; + + return Visit(Body); + } + +public: + DerefAnalysisVisitor(const TemplateArgumentList &ArgList, + const CXXRecordDecl *ClassDecl) + : ArgList(&ArgList), ClassDecl(ClassDecl) {} + + DerefAnalysisVisitor(const CXXRecordDecl *ClassDecl) : ClassDecl(ClassDecl) {} + + std::optional<bool> HasSpecializedDelete(CXXMethodDecl *Decl) { + if (auto *Body = Decl->getBody()) + return VisitBody(Body); + if (auto *Tmpl = Decl->getTemplateInstantiationPattern()) + return std::nullopt; // Indeterminate. There was no concrete instance. + return false; + } + + bool VisitCallExpr(const CallExpr *CE) { + auto *Callee = CE->getCallee(); + while (auto *Expr = dyn_cast<CastExpr>(Callee)) + Callee = Expr->getSubExpr(); + if (auto *DeclRef = dyn_cast<DeclRefExpr>(Callee)) { + auto *Decl = DeclRef->getDecl(); + if (auto *VD = dyn_cast<VarDecl>(Decl)) { + if (auto *Init = VD->getInit()) { ---------------- haoNoQ wrote:
I mean, the only thing you can call on a lambda-type variable, is that lambda's `operator()()`. And it can't be any other lambda's `operator()()` because you can't assign lambdas to each other even when they have the same signature. So I suspect that if you simply ask the AST for `CE->getCalleeDecl()` or `CE->getDirectCallee()` or something of that nature, it'll give you the declaration of `operator()()` without any extra steps, and it'll fit in naturally with the rest of the code so the `getInit()` branch can be completely deleted. I might be wrong, needs testing. https://github.com/llvm/llvm-project/pull/92837 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits