https://github.com/hjanuschka updated https://github.com/llvm/llvm-project/pull/117529
>From b0ca775e68d018b1ad9aa0e4db7358f572919ac3 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. Additionally, add a new 'misc-make-smart-ptr' check that allows matching custom smart pointer types without overriding the defaults of the modernize checks. This check has no default type or function configured and must be explicitly set up by the user. --- .../clang-tidy/misc/CMakeLists.txt | 2 + .../clang-tidy/misc/MakeSmartPtrCheck.cpp | 39 ++++++++++ .../clang-tidy/misc/MakeSmartPtrCheck.h | 37 +++++++++ .../clang-tidy/misc/MiscTidyModule.cpp | 2 + .../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 | 19 +++++ .../docs/clang-tidy/checks/list.rst | 1 + .../clang-tidy/checks/misc/make-smart-ptr.rst | 61 +++++++++++++++ .../checks/modernize/make-shared.rst | 5 ++ .../checks/modernize/make-unique.rst | 5 ++ .../checkers/misc/make-smart-ptr.cpp | 55 +++++++++++++ .../modernize/make-shared-ptr-name.cpp | 60 +++++++++++++++ .../modernize/make-unique-ptr-name.cpp | 77 +++++++++++++++++++ 16 files changed, 376 insertions(+), 6 deletions(-) create mode 100644 clang-tools-extra/clang-tidy/misc/MakeSmartPtrCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/misc/MakeSmartPtrCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/misc/make-smart-ptr.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/make-smart-ptr.cpp 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/misc/CMakeLists.txt b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt index e34b0cf687be3..48749341193ca 100644 --- a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt @@ -25,6 +25,7 @@ add_clang_library(clangTidyMiscModule STATIC ConfusableIdentifierCheck.cpp HeaderIncludeCycleCheck.cpp IncludeCleanerCheck.cpp + MakeSmartPtrCheck.cpp MiscTidyModule.cpp MisleadingBidirectionalCheck.cpp MisleadingIdentifierCheck.cpp @@ -49,6 +50,7 @@ add_clang_library(clangTidyMiscModule STATIC LINK_LIBS clangTidy + clangTidyModernizeModule clangTidyUtils DEPENDS diff --git a/clang-tools-extra/clang-tidy/misc/MakeSmartPtrCheck.cpp b/clang-tools-extra/clang-tidy/misc/MakeSmartPtrCheck.cpp new file mode 100644 index 0000000000000..887517b91b7a8 --- /dev/null +++ b/clang-tools-extra/clang-tidy/misc/MakeSmartPtrCheck.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "MakeSmartPtrCheck.h" + +// FixItHint - Hint to check documentation script to mark this check as +// providing a FixIt. + +using namespace clang::ast_matchers; + +namespace clang::tidy::misc { + +MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context) + : modernize::MakeSmartPtrCheck(Name, Context, "", "") {} + +MakeSmartPtrCheck::SmartPtrTypeMatcher +MakeSmartPtrCheck::getSmartPointerTypeMatcher() const { + return qualType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(classTemplateSpecializationDecl( + hasName(MakeSmartPtrType), templateArgumentCountIs(1), + hasTemplateArgument(0, templateArgument(refersToType( + qualType().bind(PointerType))))))))); +} + +bool MakeSmartPtrCheck::isLanguageVersionSupported( + const LangOptions &LangOpts) const { + // This check requires both MakeSmartPtrType and MakeSmartPtrFunction to be + // configured. If either is empty (the default), disable the check. + if (MakeSmartPtrType.empty()) + return false; + return LangOpts.CPlusPlus11; +} + +} // namespace clang::tidy::misc diff --git a/clang-tools-extra/clang-tidy/misc/MakeSmartPtrCheck.h b/clang-tools-extra/clang-tidy/misc/MakeSmartPtrCheck.h new file mode 100644 index 0000000000000..8a56c3ca4535c --- /dev/null +++ b/clang-tools-extra/clang-tidy/misc/MakeSmartPtrCheck.h @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MAKESMARTPTRCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MAKESMARTPTRCHECK_H + +#include "../modernize/MakeSmartPtrCheck.h" + +namespace clang::tidy::misc { + +/// Finds constructions of custom smart pointer types from raw ``new`` +/// expressions and replaces them with a configurable factory function. +/// +/// Unlike ``modernize-make-shared`` and ``modernize-make-unique``, this check +/// has no default smart pointer type or factory function. Both +/// ``MakeSmartPtrType`` and ``MakeSmartPtrFunction`` must be configured for the +/// check to produce diagnostics. +/// +/// For the user-facing documentation see: +/// https://clang.llvm.org/extra/clang-tidy/checks/misc/make-smart-ptr.html +class MakeSmartPtrCheck : public modernize::MakeSmartPtrCheck { +public: + MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context); + +protected: + SmartPtrTypeMatcher getSmartPointerTypeMatcher() const override; + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override; +}; + +} // namespace clang::tidy::misc + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MAKESMARTPTRCHECK_H diff --git a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp index f8550b30b9789..c6354df755611 100644 --- a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp @@ -15,6 +15,7 @@ #include "DefinitionsInHeadersCheck.h" #include "HeaderIncludeCycleCheck.h" #include "IncludeCleanerCheck.h" +#include "MakeSmartPtrCheck.h" #include "MisleadingBidirectionalCheck.h" #include "MisleadingIdentifierCheck.h" #include "MisplacedConstCheck.h" @@ -56,6 +57,7 @@ class MiscModule : public ClangTidyModule { CheckFactories.registerCheck<HeaderIncludeCycleCheck>( "misc-header-include-cycle"); CheckFactories.registerCheck<IncludeCleanerCheck>("misc-include-cleaner"); + CheckFactories.registerCheck<MakeSmartPtrCheck>("misc-make-smart-ptr"); CheckFactories.registerCheck<MisleadingBidirectionalCheck>( "misc-misleading-bidirectional"); CheckFactories.registerCheck<MisleadingIdentifierCheck>( 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..364985cb62176 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -121,6 +121,15 @@ New checks ``llvm::to_vector(llvm::make_filter_range(...))`` that can be replaced with ``llvm::map_to_vector`` and ``llvm::filter_to_vector``. +- New :doc:`misc-make-smart-ptr + <clang-tidy/checks/misc/make-smart-ptr>` check. + + Finds constructions of custom smart pointer types from raw ``new`` expressions + and replaces them with a configurable factory function. Unlike + ``modernize-make-shared`` and ``modernize-make-unique``, this check requires + explicit configuration and allows using custom smart pointer types without + losing the default ``std::shared_ptr``/``std::unique_ptr`` support. + - New :doc:`modernize-use-string-view <clang-tidy/checks/modernize/use-string-view>` check. @@ -205,6 +214,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/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index c475870ed7b31..4840cec6d0c13 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -268,6 +268,7 @@ Clang-Tidy Checks :doc:`misc-definitions-in-headers <misc/definitions-in-headers>`, "Yes" :doc:`misc-header-include-cycle <misc/header-include-cycle>`, :doc:`misc-include-cleaner <misc/include-cleaner>`, "Yes" + :doc:`misc-make-smart-ptr <misc/make-smart-ptr>`, "Yes" :doc:`misc-misleading-bidirectional <misc/misleading-bidirectional>`, :doc:`misc-misleading-identifier <misc/misleading-identifier>`, :doc:`misc-misplaced-const <misc/misplaced-const>`, diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/make-smart-ptr.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/make-smart-ptr.rst new file mode 100644 index 0000000000000..b72bce298c8f7 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/misc/make-smart-ptr.rst @@ -0,0 +1,61 @@ +.. title:: clang-tidy - misc-make-smart-ptr + +misc-make-smart-ptr +==================== + +Finds constructions of custom smart pointer types from raw ``new`` expressions +and replaces them with a configurable factory function. + +Unlike :doc:`modernize-make-shared <../modernize/make-shared>` and +:doc:`modernize-make-unique <../modernize/make-unique>`, this check has no +default smart pointer type or factory function. Both ``MakeSmartPtrType`` and +``MakeSmartPtrFunction`` must be configured for the check to produce +diagnostics. + +This allows using the ``modernize-make-shared`` and ``modernize-make-unique`` +checks with their default ``std::shared_ptr``/``std::unique_ptr`` types, while +also matching additional custom smart pointer types through this check. + +.. code-block:: c++ + + // Given MakeSmartPtrType = '::base::scoped_refptr' + // MakeSmartPtrFunction = 'base::MakeRefCounted' + base::scoped_refptr<Foo> ptr(new Foo(1, 2)); + + // becomes + + auto ptr = base::MakeRefCounted<Foo>(1, 2); + +Options +------- + +.. option:: MakeSmartPtrFunction + + A string specifying the name of the factory function. This option must be + set for the check to work. Default is empty. + +.. option:: MakeSmartPtrFunctionHeader + + A string specifying the corresponding header of the factory function. + Default is empty. + +.. option:: MakeSmartPtrType + + A string specifying the smart pointer type to match. This option must be + set for the check to work. Default is empty. + +.. option:: IncludeStyle + + A string specifying which include-style is used, `llvm` or `google`. Default + is `llvm`. + +.. option:: IgnoreMacros + + If set to `true`, the check will not give warnings inside macros. Default + is `true`. + +.. option:: IgnoreDefaultInitialization + + If set to `false`, the check does not suggest edits that will transform + default initialization into value initialization, as this can cause + performance regressions. Default is `true`. 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/misc/make-smart-ptr.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/make-smart-ptr.cpp new file mode 100644 index 0000000000000..72ac2612581e9 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/make-smart-ptr.cpp @@ -0,0 +1,55 @@ +// RUN: %check_clang_tidy %s misc-make-smart-ptr %t -- \ +// RUN: -config="{CheckOptions: [{key: misc-make-smart-ptr.MakeSmartPtrType, value: '::base::scoped_refptr'}, \ +// RUN: {key: misc-make-smart-ptr.MakeSmartPtrFunction, value: 'base::MakeRefCounted'}, \ +// RUN: {key: misc-make-smart-ptr.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); +}; + +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 Base(1, 2)); + // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use base::MakeRefCounted instead + // CHECK-FIXES: P1 = base::MakeRefCounted<Base>(1, 2); +} + +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-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
