https://github.com/rniwa updated 
https://github.com/llvm/llvm-project/pull/178824

>From 1ae2ec2568ecd5884b0fd3662b75d2a142c065d9 Mon Sep 17 00:00:00 2001
From: Ryosuke Niwa <[email protected]>
Date: Thu, 29 Jan 2026 19:31:35 -0800
Subject: [PATCH 1/3] [alpha.webkit.NoDeleteChecker] Don't emit a warning for a
 function without annotation.

This PR fixes the bug in alpha.webkit.NoDeleteChecker that it emits a warning 
for any
function without [[clang::annotate_type("webkit.nodelete")]] annotation if it 
contains
non-trivial code. It also fixes a bug hat we weren't checking the presence of 
the
annotation on superclass' corresponding member functions.
---
 .../Checkers/WebKit/NoDeleteChecker.cpp           | 15 ++++++++++++---
 .../Checkers/WebKit/nodelete-annotation.cpp       |  4 ++++
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/NoDeleteChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/WebKit/NoDeleteChecker.cpp
index 397fda8cd67ed..482cdb3f96ec2 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/NoDeleteChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/NoDeleteChecker.cpp
@@ -70,6 +70,12 @@ class NoDeleteChecker : public 
Checker<check::ASTDecl<TranslationUnitDecl>> {
       return;
 
     bool HasNoDeleteAnnotation = isNoDeleteFunction(FD);
+    for (auto* D = FD->getPreviousDecl(); D; D = D->getPreviousDecl()) {
+      if (isNoDeleteFunction(D)) {
+        HasNoDeleteAnnotation = true;
+        break;
+      }
+    }
     if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
       if (auto *Cls = MD->getParent(); Cls && MD->isVirtual()) {
         CXXBasePaths Paths;
@@ -84,18 +90,21 @@ class NoDeleteChecker : public 
Checker<check::ASTDecl<TranslationUnitDecl>> {
               const CXXRecordDecl *R = T->getAsCXXRecordDecl();
               for (const CXXMethodDecl *BaseMD : R->methods()) {
                 if (BaseMD->getCorrespondingMethodInClass(Cls) == MD) {
-                  if (isNoDeleteFunction(FD)) {
+                  if (isNoDeleteFunction(BaseMD)) {
                     HasNoDeleteAnnotation = true;
-                    return false;
+                    return true;
                   }
                 }
               }
-              return true;
+              return false;
             },
             Paths, /*LookupInDependent =*/true);
       }
     }
 
+    if (!HasNoDeleteAnnotation)
+      return;
+
     auto Body = FD->getBody();
     if (!Body || TFA.isTrivial(Body))
       return;
diff --git a/clang/test/Analysis/Checkers/WebKit/nodelete-annotation.cpp 
b/clang/test/Analysis/Checkers/WebKit/nodelete-annotation.cpp
index b23fd007ff789..121719400d08b 100644
--- a/clang/test/Analysis/Checkers/WebKit/nodelete-annotation.cpp
+++ b/clang/test/Analysis/Checkers/WebKit/nodelete-annotation.cpp
@@ -3,6 +3,10 @@
 void someFunction();
 void [[clang::annotate_type("webkit.nodelete")]] safeFunction();
 
+void functionWithoutNoDeleteAnnotation() {
+  someFunction();
+}
+
 void [[clang::annotate_type("webkit.nodelete")]] callsUnsafe() {
   // expected-warning@-1{{A function 'callsUnsafe' has 
[[clang::annotate_type("webkit.nodelete")]] but it contains code that could 
destruct an object}}
   someFunction();

>From 8448d4ec62179d1cbf823459a6fd8ec23a904001 Mon Sep 17 00:00:00 2001
From: Ryosuke Niwa <[email protected]>
Date: Fri, 30 Jan 2026 12:22:35 -0800
Subject: [PATCH 2/3] Address the review comments by simplyfing the check for
 webkit.nodelete annotation.

---
 .../Checkers/WebKit/NoDeleteChecker.cpp       | 54 +++++++------------
 1 file changed, 20 insertions(+), 34 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/NoDeleteChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/WebKit/NoDeleteChecker.cpp
index 482cdb3f96ec2..23d6d38cf1bc3 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/NoDeleteChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/NoDeleteChecker.cpp
@@ -65,44 +65,30 @@ class NoDeleteChecker : public 
Checker<check::ASTDecl<TranslationUnitDecl>> {
     visitor.TraverseDecl(const_cast<TranslationUnitDecl *>(TUD));
   }
 
-  void visitFunctionDecl(const FunctionDecl *FD) const {
-    if (!FD->doesThisDeclarationHaveABody())
-      return;
+  static bool hasNoDeleteAnnotation(const FunctionDecl *FD) {
+      if (llvm::any_of(FD->redecls(), isNoDeleteFunction))
+        return true;
 
-    bool HasNoDeleteAnnotation = isNoDeleteFunction(FD);
-    for (auto* D = FD->getPreviousDecl(); D; D = D->getPreviousDecl()) {
-      if (isNoDeleteFunction(D)) {
-        HasNoDeleteAnnotation = true;
-        break;
-      }
-    }
-    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(BaseMD)) {
-                    HasNoDeleteAnnotation = true;
-                    return true;
-                  }
-                }
-              }
-              return false;
-            },
-            Paths, /*LookupInDependent =*/true);
+      const auto *MD = dyn_cast<CXXMethodDecl>(FD);
+      if (!MD || !MD->isVirtual())
+        return false;
+
+      auto Overriders = llvm::to_vector(MD->overridden_methods());
+      while (!Overriders.empty()) {
+        const auto *Fn = Overriders.pop_back_val();
+        llvm::append_range(Overriders, Fn->overridden_methods());
+        if (isNoDeleteFunction(Fn))
+          return true;
       }
+
+      return false;
     }
 
-    if (!HasNoDeleteAnnotation)
+  void visitFunctionDecl(const FunctionDecl *FD) const {
+    if (!FD->doesThisDeclarationHaveABody())
+      return;
+
+    if (!hasNoDeleteAnnotation(FD))
       return;
 
     auto Body = FD->getBody();

>From 07ecc8e3c281b6c40bfebef17e323a1329bc9794 Mon Sep 17 00:00:00 2001
From: Ryosuke Niwa <[email protected]>
Date: Fri, 30 Jan 2026 12:51:09 -0800
Subject: [PATCH 3/3] Fix formatting.

---
 .../Checkers/WebKit/NoDeleteChecker.cpp       | 28 +++++++++----------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/NoDeleteChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/WebKit/NoDeleteChecker.cpp
index 23d6d38cf1bc3..2740890704767 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/NoDeleteChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/NoDeleteChecker.cpp
@@ -66,24 +66,24 @@ class NoDeleteChecker : public 
Checker<check::ASTDecl<TranslationUnitDecl>> {
   }
 
   static bool hasNoDeleteAnnotation(const FunctionDecl *FD) {
-      if (llvm::any_of(FD->redecls(), isNoDeleteFunction))
-        return true;
-
-      const auto *MD = dyn_cast<CXXMethodDecl>(FD);
-      if (!MD || !MD->isVirtual())
-        return false;
-
-      auto Overriders = llvm::to_vector(MD->overridden_methods());
-      while (!Overriders.empty()) {
-        const auto *Fn = Overriders.pop_back_val();
-        llvm::append_range(Overriders, Fn->overridden_methods());
-        if (isNoDeleteFunction(Fn))
-          return true;
-      }
+    if (llvm::any_of(FD->redecls(), isNoDeleteFunction))
+      return true;
 
+    const auto *MD = dyn_cast<CXXMethodDecl>(FD);
+    if (!MD || !MD->isVirtual())
       return false;
+
+    auto Overriders = llvm::to_vector(MD->overridden_methods());
+    while (!Overriders.empty()) {
+      const auto *Fn = Overriders.pop_back_val();
+      llvm::append_range(Overriders, Fn->overridden_methods());
+      if (isNoDeleteFunction(Fn))
+        return true;
     }
 
+    return false;
+  }
+
   void visitFunctionDecl(const FunctionDecl *FD) const {
     if (!FD->doesThisDeclarationHaveABody())
       return;

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to