[clang-tools-extra] [clang-tidy] cppcoreguidelines-owning-memory: support new expressions through implicit casts (PR #189544)
Yukari Kaname via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 31 00:49:25 PDT 2026
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 <yukari at aliciaworks.com>
Date: Tue, 31 Mar 2026 14:01:17 +0800
Subject: [PATCH] [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();
More information about the cfe-commits
mailing list