https://github.com/yukarikaname updated 
https://github.com/llvm/llvm-project/pull/189544

>From 4299595400641a1f7101b8749e629d47e6ddc2ba Mon Sep 17 00:00:00 2001
From: Yukari Kaname <[email protected]>
Date: Tue, 31 Mar 2026 14:01:17 +0800
Subject: [PATCH 1/2] [clang-tidy] cppcoreguidelines-owning-memory: handle new
 expressions wrapped in implicit casts and add regression tests for
 derived-to-base new returns/assignments

---
 .../cppcoreguidelines/OwningMemoryCheck.cpp    | 18 ++++++++++--------
 clang-tools-extra/docs/ReleaseNotes.rst        |  4 ++++
 .../cppcoreguidelines/owning-memory.cpp        | 18 ++++++++++++++++++
 3 files changed, 32 insertions(+), 8 deletions(-)

diff --git 
a/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp 
b/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp
index f4e89470a80da..5a52605fa6d6a 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp
@@ -63,7 +63,8 @@ void OwningMemoryCheck::registerMatchers(MatchFinder *Finder) 
{
                 functionDecl(returns(qualType(hasDeclaration(OwnerDecl)))))),
             CreatesLegacyOwner, LegacyOwnerCast);
 
-  const auto ConsideredOwner = eachOf(IsOwnerType, CreatesOwner);
+  const auto CreatesOwnerWithCasts = ignoringImpCasts(CreatesOwner);
+  const auto ConsideredOwner = eachOf(IsOwnerType, CreatesOwnerWithCasts);
   const auto ScopeDeclaration = anyOf(translationUnitDecl(), namespaceDecl(),
                                       recordDecl(), functionDecl());
 
@@ -127,14 +128,14 @@ void OwningMemoryCheck::registerMatchers(MatchFinder 
*Finder) {
   // but the LHS is not an owner.
   Finder->addMatcher(binaryOperator(isAssignmentOperator(),
                                     hasLHS(unless(IsOwnerType)),
-                                    hasRHS(CreatesOwner))
+                                    hasRHS(CreatesOwnerWithCasts))
                          .bind("bad_owner_creation_assignment"),
                      this);
 
   // Matching on initialization operations where the initial value is a newly
   // created owner, but the LHS is not an owner.
   Finder->addMatcher(
-      traverse(TK_AsIs, namedDecl(varDecl(hasInitializer(CreatesOwner),
+      traverse(TK_AsIs, 
namedDecl(varDecl(hasInitializer(CreatesOwnerWithCasts),
                                           unless(IsOwnerType))
                                       .bind("bad_owner_creation_variable"))),
       this);
@@ -149,11 +150,12 @@ void OwningMemoryCheck::registerMatchers(MatchFinder 
*Finder) {
 
   // Matching for function calls where one argument is a created owner, but the
   // parameter type is not an owner.
-  Finder->addMatcher(callExpr(forEachArgumentWithParam(
-                         
expr(CreatesOwner).bind("bad_owner_creation_argument"),
-                         parmVarDecl(unless(IsOwnerType))
-                             .bind("bad_owner_creation_parameter"))),
-                     this);
+  Finder->addMatcher(
+      callExpr(forEachArgumentWithParam(
+          expr(CreatesOwnerWithCasts).bind("bad_owner_creation_argument"),
+          parmVarDecl(unless(IsOwnerType))
+              .bind("bad_owner_creation_parameter"))),
+      this);
 
   auto IsNotInSubLambda = stmt(
       hasAncestor(
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 69dc5b9633398..1c1233d8164e5 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -283,6 +283,10 @@ Changes in existing checks
   <clang-tidy/checks/cppcoreguidelines/missing-std-forward>` check by fixing
   a false positive for constrained template parameters.
 
+- Improved :doc:`cppcoreguidelines-owning-memory
+  <clang-tidy/checks/cppcoreguidelines/owning-memory>` check to detect `new`
+  expressions through implicit casts (e.g., `C* x = new D`).
+
 - Improved :doc:`cppcoreguidelines-pro-type-vararg
   <clang-tidy/checks/cppcoreguidelines/pro-type-vararg>` check by no longer
   warning on builtins with custom type checking (e.g., type-generic builtins
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/owning-memory.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/owning-memory.cpp
index ae61b17ca14d2..2ba8d5ce23749 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/owning-memory.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/owning-memory.cpp
@@ -398,6 +398,24 @@ namespace PR63994 {
   }
 }
 
+namespace PR64361 {
+  struct C {
+    virtual ~C() {}
+  };
+
+  struct D : public C {};
+
+  void testDerivedAssignment() {
+    C* x = new D;
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: initializing non-owner 'C *' with 
a newly created 'gsl::owner<>'
+  }
+
+  C* testDerivedReturn() {
+    return new D;
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: returning a newly created resource 
of type 'C *' or 'gsl::owner<>' from a function whose return type is not 
'gsl::owner<>'
+  }
+}
+
 namespace PR59389 {
   struct S {
     S();

>From e098b2cfa021f8c27433bffc9878602dfa5453e4 Mon Sep 17 00:00:00 2001
From: Yukari Kaname <[email protected]>
Date: Tue, 31 Mar 2026 23:17:05 +0800
Subject: [PATCH 2/2] [clang-tidy] Replace CreatesOwnerWithCasts with
 ignoringImpCasts(CreatesOwner)

---
 .../cppcoreguidelines/OwningMemoryCheck.cpp   | 25 ++++++++++---------
 clang-tools-extra/docs/ReleaseNotes.rst       |  4 +--
 2 files changed, 15 insertions(+), 14 deletions(-)

diff --git 
a/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp 
b/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp
index 5a52605fa6d6a..c8ecc2dc2ea3b 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp
@@ -63,8 +63,8 @@ void OwningMemoryCheck::registerMatchers(MatchFinder *Finder) 
{
                 functionDecl(returns(qualType(hasDeclaration(OwnerDecl)))))),
             CreatesLegacyOwner, LegacyOwnerCast);
 
-  const auto CreatesOwnerWithCasts = ignoringImpCasts(CreatesOwner);
-  const auto ConsideredOwner = eachOf(IsOwnerType, CreatesOwnerWithCasts);
+  const auto ConsideredOwner =
+      eachOf(IsOwnerType, ignoringImpCasts(CreatesOwner));
   const auto ScopeDeclaration = anyOf(translationUnitDecl(), namespaceDecl(),
                                       recordDecl(), functionDecl());
 
@@ -128,16 +128,17 @@ void OwningMemoryCheck::registerMatchers(MatchFinder 
*Finder) {
   // but the LHS is not an owner.
   Finder->addMatcher(binaryOperator(isAssignmentOperator(),
                                     hasLHS(unless(IsOwnerType)),
-                                    hasRHS(CreatesOwnerWithCasts))
+                                    hasRHS(ignoringImpCasts(CreatesOwner)))
                          .bind("bad_owner_creation_assignment"),
                      this);
 
   // Matching on initialization operations where the initial value is a newly
   // created owner, but the LHS is not an owner.
   Finder->addMatcher(
-      traverse(TK_AsIs, 
namedDecl(varDecl(hasInitializer(CreatesOwnerWithCasts),
-                                          unless(IsOwnerType))
-                                      .bind("bad_owner_creation_variable"))),
+      traverse(TK_AsIs,
+               
namedDecl(varDecl(hasInitializer(ignoringImpCasts(CreatesOwner)),
+                                 unless(IsOwnerType))
+                             .bind("bad_owner_creation_variable"))),
       this);
 
   // Match on all function calls that expect owners as arguments, but didn't
@@ -150,12 +151,12 @@ void OwningMemoryCheck::registerMatchers(MatchFinder 
*Finder) {
 
   // Matching for function calls where one argument is a created owner, but the
   // parameter type is not an owner.
-  Finder->addMatcher(
-      callExpr(forEachArgumentWithParam(
-          expr(CreatesOwnerWithCasts).bind("bad_owner_creation_argument"),
-          parmVarDecl(unless(IsOwnerType))
-              .bind("bad_owner_creation_parameter"))),
-      this);
+  Finder->addMatcher(callExpr(forEachArgumentWithParam(
+                         expr(ignoringImpCasts(CreatesOwner))
+                             .bind("bad_owner_creation_argument"),
+                         parmVarDecl(unless(IsOwnerType))
+                             .bind("bad_owner_creation_parameter"))),
+                     this);
 
   auto IsNotInSubLambda = stmt(
       hasAncestor(
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 1c1233d8164e5..b42828b17f1c8 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -284,8 +284,8 @@ Changes in existing checks
   a false positive for constrained template parameters.
 
 - Improved :doc:`cppcoreguidelines-owning-memory
-  <clang-tidy/checks/cppcoreguidelines/owning-memory>` check to detect `new`
-  expressions through implicit casts (e.g., `C* x = new D`).
+  <clang-tidy/checks/cppcoreguidelines/owning-memory>` check to detect ``new``
+  expressions through implicit casts (e.g., ``C* x = new D``).
 
 - Improved :doc:`cppcoreguidelines-pro-type-vararg
   <clang-tidy/checks/cppcoreguidelines/pro-type-vararg>` check by no longer

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

Reply via email to