https://github.com/yukarikaname updated https://github.com/llvm/llvm-project/pull/189544
>From 01997babb6e26dfcfdbb5cf5e3b486ccbc7c44b8 Mon Sep 17 00:00:00 2001 From: Yukari Kaname <[email protected]> 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 | 10 ++++++++++ .../cppcoreguidelines/owning-memory.cpp | 18 ++++++++++++++++++ 3 files changed, 38 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..a2f0979fd56dc 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -220,6 +220,12 @@ Changes in existing checks <clang-tidy/checks/bugprone/derived-method-shadowing-base-method>` check by correctly ignoring function templates. +- 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`). + + correctly ignoring function templates. + - Improved :doc:`bugprone-exception-escape <clang-tidy/checks/bugprone/exception-escape>` check by adding `TreatFunctionsWithoutSpecificationAsThrowing` option to support reporting @@ -283,6 +289,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(); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
