================ @@ -0,0 +1,130 @@ +//=======- NoDeleteChecker.cpp -----------------------------------*- C++ -*-==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ASTUtils.h" +#include "DiagOutputUtils.h" +#include "PtrTypesSemantics.h" +#include "clang/AST/CXXInheritance.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Analysis/DomainSpecific/CocoaConventions.h" +#include "clang/Basic/SourceLocation.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/Support/SaveAndRestore.h" + +using namespace clang; +using namespace ento; + +namespace { + +class NoDeleteChecker : public Checker<check::ASTDecl<TranslationUnitDecl>> { + BugType Bug; + mutable BugReporter *BR = nullptr; + mutable TrivialFunctionAnalysis TFA; + +public: + NoDeleteChecker() + : Bug(this, + "Incorrect [[clang::annotate_type(\"webkit.nodelete\")]] " + "annotation", + "WebKit coding guidelines") {} + + void checkASTDecl(const TranslationUnitDecl *TUD, AnalysisManager &MGR, + BugReporter &BRArg) const { + BR = &BRArg; + + // The calls to checkAST* from AnalysisConsumer don't + // visit template instantiations or lambda classes. We + // want to visit those, so we make our own RecursiveASTVisitor. + struct LocalVisitor : public RecursiveASTVisitor<LocalVisitor> { + const NoDeleteChecker *Checker; + Decl *DeclWithIssue{nullptr}; + + explicit LocalVisitor(const NoDeleteChecker *Checker) : Checker(Checker) { + assert(Checker); + } + + bool shouldVisitTemplateInstantiations() const { return true; } + bool shouldVisitImplicitCode() const { return false; } + + bool VisitFunctionDecl(FunctionDecl *FD) { + Checker->visitFunctionDecl(FD); + return true; + } + }; + + LocalVisitor visitor(this); + visitor.TraverseDecl(const_cast<TranslationUnitDecl *>(TUD)); + } + + void visitFunctionDecl(const FunctionDecl *FD) const { + if (!FD->doesThisDeclarationHaveABody()) + return; + + bool HasNoDeleteAnnotation = isNoDeleteFunction(FD); + if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) { + if (auto *Cls = MD->getParent(); Cls && MD->isVirtual()) { + CXXBasePaths Paths; + Paths.setOrigin(Cls); + + Cls->lookupInBases( + [&](const CXXBaseSpecifier *Base, CXXBasePath &) { + const Type *T = Base->getType().getTypePtrOrNull(); + if (!T) + return false; + + const CXXRecordDecl *R = T->getAsCXXRecordDecl(); + for (const CXXMethodDecl *BaseMD : R->methods()) { + if (BaseMD->getCorrespondingMethodInClass(Cls) == MD) { + if (isNoDeleteFunction(FD)) { + HasNoDeleteAnnotation = true; + return false; + } + } + } + return true; + }, + Paths, /*LookupInDependent =*/true); + } + } + + auto Body = FD->getBody(); + if (!Body || TFA.isTrivial(Body)) + return; ---------------- rniwa wrote:
Yeah, I think that might be a nice follow up. I often need to investigate why a given code isn't a trivial so that'll aid me in that too. https://github.com/llvm/llvm-project/pull/177839 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
