Author: Liu Ke
Date: 2025-09-01T16:33:29+08:00
New Revision: 38268ecab94b90a2eea6c62c5911679d93954651

URL: 
https://github.com/llvm/llvm-project/commit/38268ecab94b90a2eea6c62c5911679d93954651
DIFF: 
https://github.com/llvm/llvm-project/commit/38268ecab94b90a2eea6c62c5911679d93954651.diff

LOG: [clang-tidy] Support direct initialization in modernize smart pointer 
(#154732)

Support for direct initialization detection in modernize smart pointer checks.

Added: 
    

Modified: 
    clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
    clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
    clang-tools-extra/test/clang-tidy/checkers/modernize/make-shared.cpp
    clang-tools-extra/test/clang-tidy/checkers/modernize/make-unique.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
index cea48ce6f4564..ac8476bb2f8a4 100644
--- a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
@@ -17,6 +17,7 @@ using namespace clang::ast_matchers;
 namespace clang::tidy::modernize {
 
 static constexpr char ConstructorCall[] = "constructorCall";
+static constexpr char DirectVar[] = "directVar";
 static constexpr char ResetCall[] = "resetCall";
 static constexpr char NewExpression[] = "newExpression";
 
@@ -78,18 +79,18 @@ void 
MakeSmartPtrCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
   auto IsPlacement = hasAnyPlacementArg(anything());
 
   Finder->addMatcher(
-      traverse(
-          TK_AsIs,
-          cxxBindTemporaryExpr(has(ignoringParenImpCasts(
-              cxxConstructExpr(
-                  hasType(getSmartPointerTypeMatcher()), argumentCountIs(1),
-                  hasArgument(
-                      0, cxxNewExpr(hasType(pointsTo(qualType(hasCanonicalType(
-                                        equalsBoundNode(PointerType))))),
-                                    CanCallCtor, unless(IsPlacement))
-                             .bind(NewExpression)),
-                  unless(isInTemplateInstantiation()))
-                  .bind(ConstructorCall))))),
+      traverse(TK_AsIs,
+               cxxConstructExpr(
+                   anyOf(hasParent(cxxBindTemporaryExpr()),
+                         hasParent(varDecl().bind(DirectVar))),
+                   hasType(getSmartPointerTypeMatcher()), argumentCountIs(1),
+                   hasArgument(
+                       0, 
cxxNewExpr(hasType(pointsTo(qualType(hasCanonicalType(
+                                         equalsBoundNode(PointerType))))),
+                                     CanCallCtor, unless(IsPlacement))
+                              .bind(NewExpression)),
+                   unless(isInTemplateInstantiation()))
+                   .bind(ConstructorCall)),
       this);
 
   Finder->addMatcher(
@@ -116,6 +117,7 @@ void MakeSmartPtrCheck::check(const 
MatchFinder::MatchResult &Result) {
   SourceManager &SM = *Result.SourceManager;
   const auto *Construct =
       Result.Nodes.getNodeAs<CXXConstructExpr>(ConstructorCall);
+  const auto *DVar = Result.Nodes.getNodeAs<VarDecl>(DirectVar);
   const auto *Reset = Result.Nodes.getNodeAs<CXXMemberCallExpr>(ResetCall);
   const auto *Type = Result.Nodes.getNodeAs<QualType>(PointerType);
   const auto *New = Result.Nodes.getNodeAs<CXXNewExpr>(NewExpression);
@@ -138,13 +140,14 @@ void MakeSmartPtrCheck::check(const 
MatchFinder::MatchResult &Result) {
   if (!Initializes && IgnoreDefaultInitialization)
     return;
   if (Construct)
-    checkConstruct(SM, Result.Context, Construct, Type, New);
+    checkConstruct(SM, Result.Context, Construct, DVar, Type, New);
   else if (Reset)
     checkReset(SM, Result.Context, Reset, New);
 }
 
 void MakeSmartPtrCheck::checkConstruct(SourceManager &SM, ASTContext *Ctx,
                                        const CXXConstructExpr *Construct,
+                                       const VarDecl *DVar,
                                        const QualType *Type,
                                        const CXXNewExpr *New) {
   SourceLocation ConstructCallStart = Construct->getExprLoc();
@@ -187,9 +190,14 @@ void MakeSmartPtrCheck::checkConstruct(SourceManager &SM, 
ASTContext *Ctx,
     ConstructCallEnd = ConstructCallStart.getLocWithOffset(LAngle);
   }
 
+  std::string FinalMakeSmartPtrFunctionName = MakeSmartPtrFunctionName.str();
+  if (DVar)
+    FinalMakeSmartPtrFunctionName =
+        ExprStr.str() + " = " + MakeSmartPtrFunctionName.str();
+
   Diag << FixItHint::CreateReplacement(
       CharSourceRange::getCharRange(ConstructCallStart, ConstructCallEnd),
-      MakeSmartPtrFunctionName);
+      FinalMakeSmartPtrFunctionName);
 
   // If the smart_ptr is built with brace enclosed direct initialization, use
   // parenthesis instead.

diff  --git a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h 
b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
index 02374dc06d9be..e2f9abed8138a 100644
--- a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
@@ -51,8 +51,8 @@ class MakeSmartPtrCheck : public ClangTidyCheck {
   const bool IgnoreDefaultInitialization;
 
   void checkConstruct(SourceManager &SM, ASTContext *Ctx,
-                      const CXXConstructExpr *Construct, const QualType *Type,
-                      const CXXNewExpr *New);
+                      const CXXConstructExpr *Construct, const VarDecl *DVar,
+                      const QualType *Type, const CXXNewExpr *New);
   void checkReset(SourceManager &SM, ASTContext *Ctx,
                   const CXXMemberCallExpr *Reset, const CXXNewExpr *New);
 

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/modernize/make-shared.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/modernize/make-shared.cpp
index e57f45c4127f9..65ece773b7c1f 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/make-shared.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/make-shared.cpp
@@ -109,6 +109,8 @@ void basic() {
   }
 
   std::shared_ptr<int> R(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_shared instead
+  // CHECK-FIXES: std::shared_ptr<int> R = std::make_shared<int>();
   std::shared_ptr<int> S(new int);
 
   // Create the shared_ptr as a parameter to a function.

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/modernize/make-unique.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/modernize/make-unique.cpp
index e665ca0a15a68..13103c735276a 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/make-unique.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/make-unique.cpp
@@ -154,6 +154,8 @@ void basic() {
   }
 
   std::unique_ptr<int> R(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<int> R = std::make_unique<int>();
   std::unique_ptr<int> S(new int);
 
   // Create the unique_ptr as a parameter to a function.


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

Reply via email to