[clang] [alpha.webkit.NoDeleteChecker] Allow no-delete default constructors (PR #201544)

via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 4 03:43:35 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Ryosuke Niwa (rniwa)

<details>
<summary>Changes</summary>

This PR fixes the bug in TrivialFunctionAnalysis that it treats a default constructor without an explicit body / definition as not "trivial". Fixed the bug by allowing the function body to be missing when isThisDeclarationADefinition is true.

---
Full diff: https://github.com/llvm/llvm-project/pull/201544.diff


2 Files Affected:

- (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp (+6-2) 
- (modified) clang/test/Analysis/Checkers/WebKit/nodelete-annotation.cpp (+42) 


``````````diff
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
index d5ed7fc78148a..4a51914791423 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
@@ -652,7 +652,8 @@ class TrivialFunctionAnalysisVisitor
   bool IsFunctionTrivial(const Decl *D) {
     const Stmt **SavedOffendingStmt = std::exchange(OffendingStmt, nullptr);
     auto Result = WithCachedResult(D, [&]() {
-      if (auto *FnDecl = dyn_cast<FunctionDecl>(D)) {
+      auto *FnDecl = dyn_cast<FunctionDecl>(D);
+      if (FnDecl) {
         if (isNoDeleteFunction(FnDecl))
           return true;
         if (auto *MD = dyn_cast<CXXMethodDecl>(D); MD && MD->isVirtual())
@@ -669,8 +670,11 @@ class TrivialFunctionAnalysisVisitor
         }
       }
       const Stmt *Body = D->getBody();
-      if (!Body)
+      if (!Body) {
+        if (FnDecl && FnDecl->isThisDeclarationADefinition())
+          return true;
         return false;
+      }
       return Visit(Body);
     });
     OffendingStmt = SavedOffendingStmt;
diff --git a/clang/test/Analysis/Checkers/WebKit/nodelete-annotation.cpp b/clang/test/Analysis/Checkers/WebKit/nodelete-annotation.cpp
index a9c50cfb1f45f..0d78fa91046ed 100644
--- a/clang/test/Analysis/Checkers/WebKit/nodelete-annotation.cpp
+++ b/clang/test/Analysis/Checkers/WebKit/nodelete-annotation.cpp
@@ -701,3 +701,45 @@ Ref<RefCountable> [[clang::annotate_type("webkit.nodelete")]] returnTypedefPrval
 
 } // namespace returned_prvalue_typedef
 
+namespace create_with_default_constructor {
+
+  struct ObjectWithDefaultConstructorWithoutMemberVariables {
+    void ref() const;
+    void deref() const;
+
+    static auto [[clang::annotate_type("webkit.nodelete")]] create() {
+      return adoptRef(*new ObjectWithDefaultConstructorWithoutMemberVariables());
+    }
+  };
+
+  struct ObjectWithDefaultConstructorWithPODMemberVariables {
+    void ref() const;
+    void deref() const;
+
+    static auto [[clang::annotate_type("webkit.nodelete")]] create() {
+      return adoptRef(*new ObjectWithDefaultConstructorWithPODMemberVariables());
+    }
+
+  private:
+    int value { 0 };
+    RefCountable* ptr { nullptr };
+  };
+
+  struct ObjectWithOpaqueCtor {
+    ObjectWithOpaqueCtor();
+  };
+
+  struct ObjectWithDefaultConstructorWithOpaqueCtorMemberVariables {
+    void ref() const;
+    void deref() const;
+
+    static auto [[clang::annotate_type("webkit.nodelete")]] create() {
+      return adoptRef(*new ObjectWithDefaultConstructorWithOpaqueCtorMemberVariables());
+      // expected-warning at -1{{A function 'create' has [[clang::annotate_type("webkit.nodelete")]] but it contains code that could destruct an object}}
+    }
+
+  private:
+    ObjectWithOpaqueCtor obj;
+  };
+
+} // namespace create_with_default_constructor

``````````

</details>


https://github.com/llvm/llvm-project/pull/201544


More information about the cfe-commits mailing list