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
