[clang-tools-extra] [clang-tidy] modernize-make-shared: Add MakeSmartPtrType option (PR #117529)
Helmut Januschka via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 18 01:33:38 PST 2026
https://github.com/hjanuschka updated https://github.com/llvm/llvm-project/pull/117529
>From d947d7010dcef138969ddef0cf5a35e6dfb0aeec Mon Sep 17 00:00:00 2001
From: Helmut Januschka <helmut at januschka.com>
Date: Wed, 18 Feb 2026 10:33:19 +0100
Subject: [PATCH] [clang-tidy] modernize-make-shared/unique: Add
MakeSmartPtrType option
Add a new 'MakeSmartPtrType' option to the modernize-make-shared and
modernize-make-unique checks, allowing users to specify a custom smart
pointer type to match (e.g. base::scoped_refptr) instead of only
matching std::shared_ptr/std::unique_ptr.
The option defaults to '::std::shared_ptr' for make-shared and
'::std::unique_ptr' for make-unique, preserving existing behavior.
---
.../clang-tidy/modernize/MakeSharedCheck.cpp | 5 +-
.../modernize/MakeSmartPtrCheck.cpp | 5 +-
.../clang-tidy/modernize/MakeSmartPtrCheck.h | 4 +-
.../clang-tidy/modernize/MakeUniqueCheck.cpp | 5 +-
clang-tools-extra/docs/ReleaseNotes.rst | 10 +++
.../checks/modernize/make-shared.rst | 5 ++
.../checks/modernize/make-unique.rst | 5 ++
.../modernize/make-shared-ptr-name.cpp | 60 +++++++++++++++
.../modernize/make-unique-ptr-name.cpp | 77 +++++++++++++++++++
9 files changed, 170 insertions(+), 6 deletions(-)
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/make-shared-ptr-name.cpp
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/make-unique-ptr-name.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/MakeSharedCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MakeSharedCheck.cpp
index 207195551883b..2a2d20499db73 100644
--- a/clang-tools-extra/clang-tidy/modernize/MakeSharedCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/MakeSharedCheck.cpp
@@ -16,13 +16,14 @@ using namespace clang::ast_matchers;
namespace clang::tidy::modernize {
MakeSharedCheck::MakeSharedCheck(StringRef Name, ClangTidyContext *Context)
- : MakeSmartPtrCheck(Name, Context, "std::make_shared") {}
+ : MakeSmartPtrCheck(Name, Context, "std::make_shared",
+ "::std::shared_ptr") {}
MakeSharedCheck::SmartPtrTypeMatcher
MakeSharedCheck::getSmartPointerTypeMatcher() const {
return qualType(hasUnqualifiedDesugaredType(
recordType(hasDeclaration(classTemplateSpecializationDecl(
- hasName("::std::shared_ptr"), templateArgumentCountIs(1),
+ hasName(MakeSmartPtrType), templateArgumentCountIs(1),
hasTemplateArgument(0, templateArgument(refersToType(
qualType().bind(PointerType)))))))));
}
diff --git a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
index 42a60bb897028..33881b5810db3 100644
--- a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
@@ -34,8 +34,10 @@ static std::string getNewExprName(const CXXNewExpr *NewExpr,
}
MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context,
- StringRef MakeSmartPtrFunctionName)
+ StringRef MakeSmartPtrFunctionName,
+ StringRef MakeSmartPtrType)
: ClangTidyCheck(Name, Context),
+ MakeSmartPtrType(Options.get("MakeSmartPtrType", MakeSmartPtrType)),
Inserter(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::IS_LLVM),
areDiagsSelfContained()),
@@ -50,6 +52,7 @@ MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context,
void MakeSmartPtrCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "IncludeStyle", Inserter.getStyle());
Options.store(Opts, "MakeSmartPtrFunctionHeader", MakeSmartPtrFunctionHeader);
+ Options.store(Opts, "MakeSmartPtrType", MakeSmartPtrType);
Options.store(Opts, "MakeSmartPtrFunction", MakeSmartPtrFunctionName);
Options.store(Opts, "IgnoreMacros", IgnoreMacros);
Options.store(Opts, "IgnoreDefaultInitialization",
diff --git a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
index e15ba34dcf3d3..1c60cf7df2319 100644
--- a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h
@@ -22,7 +22,8 @@ namespace clang::tidy::modernize {
class MakeSmartPtrCheck : public ClangTidyCheck {
public:
MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context,
- StringRef MakeSmartPtrFunctionName);
+ StringRef MakeSmartPtrFunctionName,
+ StringRef MakeSmartPtrType);
void registerMatchers(ast_matchers::MatchFinder *Finder) final;
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
Preprocessor *ModuleExpanderPP) override;
@@ -31,6 +32,7 @@ class MakeSmartPtrCheck : public ClangTidyCheck {
protected:
using SmartPtrTypeMatcher = ast_matchers::internal::BindableMatcher<QualType>;
+ const StringRef MakeSmartPtrType;
/// Returns matcher that match with different smart pointer types.
///
diff --git a/clang-tools-extra/clang-tidy/modernize/MakeUniqueCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MakeUniqueCheck.cpp
index b13d95633c12e..9300b346ec9a5 100644
--- a/clang-tools-extra/clang-tidy/modernize/MakeUniqueCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/MakeUniqueCheck.cpp
@@ -14,14 +14,15 @@ namespace clang::tidy::modernize {
MakeUniqueCheck::MakeUniqueCheck(StringRef Name,
clang::tidy::ClangTidyContext *Context)
- : MakeSmartPtrCheck(Name, Context, "std::make_unique"),
+ : MakeSmartPtrCheck(Name, Context, "std::make_unique",
+ "::std::unique_ptr"),
RequireCPlusPlus14(Options.get("MakeSmartPtrFunction", "").empty()) {}
MakeUniqueCheck::SmartPtrTypeMatcher
MakeUniqueCheck::getSmartPointerTypeMatcher() const {
return qualType(hasUnqualifiedDesugaredType(
recordType(hasDeclaration(classTemplateSpecializationDecl(
- hasName("::std::unique_ptr"), templateArgumentCountIs(2),
+ hasName(MakeSmartPtrType), templateArgumentCountIs(2),
hasTemplateArgument(
0, templateArgument(refersToType(qualType().bind(PointerType)))),
hasTemplateArgument(
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 68bab88146241..c84675d6ef098 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -205,6 +205,16 @@ Changes in existing checks
- Added support for analyzing function parameters with the `AnalyzeParameters`
option.
+- Improved :doc:`modernize-make-shared
+ <clang-tidy/checks/modernize/make-shared>` check by adding a new option
+ ``MakeSmartPtrType`` to specify the smart pointer type to match, with a
+ default value of ``::std::shared_ptr``.
+
+- Improved :doc:`modernize-make-unique
+ <clang-tidy/checks/modernize/make-unique>` check by adding a new option
+ ``MakeSmartPtrType`` to specify the smart pointer type to match, with a
+ default value of ``::std::unique_ptr``.
+
- Improved :doc:`modernize-pass-by-value
<clang-tidy/checks/modernize/pass-by-value>` check by adding `IgnoreMacros`
option to suppress warnings in macros.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/make-shared.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/make-shared.rst
index cd953e7ee394d..c8dcad1d5f0d2 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/make-shared.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/make-shared.rst
@@ -39,6 +39,11 @@ Options
A string specifying the corresponding header of make-shared-ptr function.
Default is `<memory>`.
+.. option:: MakeSmartPtrType
+
+ A string specifying the smart pointer type to match. Default is
+ ``::std::shared_ptr``.
+
.. option:: IncludeStyle
A string specifying which include-style is used, `llvm` or `google`. Default
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/make-unique.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/make-unique.rst
index 1aaa8701cd0f1..c279919e1bc55 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/make-unique.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/make-unique.rst
@@ -39,6 +39,11 @@ Options
A string specifying the corresponding header of make-unique-ptr function.
Default is `<memory>`.
+.. option:: MakeSmartPtrType
+
+ A string specifying the smart pointer type to match. Default is
+ ``::std::unique_ptr``.
+
.. option:: IncludeStyle
A string specifying which include-style is used, `llvm` or `google`. Default
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/make-shared-ptr-name.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/make-shared-ptr-name.cpp
new file mode 100644
index 0000000000000..98e600e500576
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/make-shared-ptr-name.cpp
@@ -0,0 +1,60 @@
+// RUN: %check_clang_tidy %s modernize-make-shared %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-make-shared.MakeSmartPtrType, value: '::base::scoped_refptr'}, \
+// RUN: {key: modernize-make-shared.MakeSmartPtrFunction, value: 'base::MakeRefCounted'}, \
+// RUN: {key: modernize-make-shared.MakeSmartPtrFunctionHeader, value: ''}]}" \
+// RUN: -- -std=c++11 -nostdinc++
+
+namespace base {
+
+template <typename T>
+class scoped_refptr {
+public:
+ scoped_refptr() : ptr_(nullptr) {}
+ explicit scoped_refptr(T *p) : ptr_(p) {}
+ scoped_refptr(const scoped_refptr &r) : ptr_(r.ptr_) {}
+ scoped_refptr(scoped_refptr &&r) : ptr_(r.ptr_) { r.ptr_ = nullptr; }
+
+ void reset(T *p = nullptr) { ptr_ = p; }
+ T *get() const { return ptr_; }
+ T &operator*() const { return *ptr_; }
+ T *operator->() const { return ptr_; }
+
+ ~scoped_refptr() {}
+
+private:
+ T *ptr_;
+};
+
+template <typename T, typename... Args>
+scoped_refptr<T> MakeRefCounted(Args &&...args) {
+ return scoped_refptr<T>(new T(args...));
+}
+
+} // namespace base
+
+struct Base {
+ Base();
+ Base(int, int);
+};
+
+struct Derived : public Base {
+ Derived();
+ Derived(int, int);
+};
+
+void testReset() {
+ base::scoped_refptr<Base> P1;
+ P1.reset(new Base());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use base::MakeRefCounted instead
+ // CHECK-FIXES: P1 = base::MakeRefCounted<Base>();
+
+ P1.reset(new Derived());
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use base::MakeRefCounted instead
+ // CHECK-FIXES: P1 = base::MakeRefCounted<Derived>();
+}
+
+base::scoped_refptr<Base> factory() {
+ return base::scoped_refptr<Base>(new Base);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use base::MakeRefCounted instead
+ // CHECK-FIXES: return base::MakeRefCounted<Base>();
+}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/make-unique-ptr-name.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/make-unique-ptr-name.cpp
new file mode 100644
index 0000000000000..3bf0209452f19
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/make-unique-ptr-name.cpp
@@ -0,0 +1,77 @@
+// RUN: %check_clang_tidy %s modernize-make-unique %t -- \
+// RUN: -config="{CheckOptions: [{key: modernize-make-unique.MakeSmartPtrType, value: '::base::unique_ptr'}, \
+// RUN: {key: modernize-make-unique.MakeSmartPtrFunction, value: 'base::make_unique'}, \
+// RUN: {key: modernize-make-unique.MakeSmartPtrFunctionHeader, value: ''}]}" \
+// RUN: -- -std=c++14 -nostdinc++
+
+namespace std {
+
+template <typename T>
+struct default_delete {
+ void operator()(T *ptr) const { delete ptr; }
+};
+
+} // namespace std
+
+namespace base {
+
+template <typename T, typename Deleter = std::default_delete<T>>
+class unique_ptr {
+public:
+ unique_ptr() : ptr_(nullptr) {}
+ explicit unique_ptr(T *p) : ptr_(p) {}
+ unique_ptr(unique_ptr &&r) : ptr_(r.ptr_) { r.ptr_ = nullptr; }
+ unique_ptr(const unique_ptr &) = delete;
+ unique_ptr &operator=(const unique_ptr &) = delete;
+ unique_ptr &operator=(unique_ptr &&r) {
+ delete ptr_;
+ ptr_ = r.ptr_;
+ r.ptr_ = nullptr;
+ return *this;
+ }
+
+ void reset(T *p = nullptr) {
+ delete ptr_;
+ ptr_ = p;
+ }
+
+ T *get() const { return ptr_; }
+ T &operator*() const { return *ptr_; }
+ T *operator->() const { return ptr_; }
+ ~unique_ptr() { delete ptr_; }
+
+private:
+ T *ptr_;
+};
+
+template <typename T, typename... Args>
+unique_ptr<T> make_unique(Args &&...args) {
+ return unique_ptr<T>(new T(args...));
+}
+
+} // namespace base
+
+struct Base {
+ Base();
+ Base(int, int);
+};
+
+void test() {
+ base::unique_ptr<Base> P1 = base::unique_ptr<Base>(new Base());
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: use base::make_unique instead [modernize-make-unique]
+ // CHECK-FIXES: base::unique_ptr<Base> P1 = base::make_unique<Base>();
+
+ P1.reset(new Base(1, 2));
+ // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use base::make_unique instead [modernize-make-unique]
+ // CHECK-FIXES: P1 = base::make_unique<Base>(1, 2);
+
+ P1 = base::unique_ptr<Base>(new Base(1, 2));
+ // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use base::make_unique instead [modernize-make-unique]
+ // CHECK-FIXES: P1 = base::make_unique<Base>(1, 2);
+}
+
+base::unique_ptr<Base> factory() {
+ return base::unique_ptr<Base>(new Base);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use base::make_unique instead [modernize-make-unique]
+ // CHECK-FIXES: return base::make_unique<Base>();
+}
More information about the cfe-commits
mailing list