================
@@ -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

Reply via email to