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 <[email protected]> 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>(); +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
