================ @@ -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()) { ---------------- rniwa wrote:
Oh I see. Indeed, it looks like we can get away with just: ```cpp bool VisitCallExpr(const CallExpr *CE) { const Decl *D = CE->getCalleeDecl(); if (D && D->hasBody()) return VisitBody(D->getBody()); return false; } ``` 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