https://github.com/hjanuschka updated https://github.com/llvm/llvm-project/pull/117529
>From d5024216b9f055328da61f2966fc8965d01de160 Mon Sep 17 00:00:00 2001 From: Helmut Januschka <[email protected]> Date: Sat, 28 Feb 2026 17:19:02 +0100 Subject: [PATCH] [clang-tidy] modernize-make-shared/unique: Add MakeSmartPtrType option --- .../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 | 4 +- clang-tools-extra/docs/ReleaseNotes.rst | 20 +++++ .../docs/clang-tidy/checks/list.rst | 1 + .../clang-tidy/checks/misc/make-smart-ptr.rst | 63 +++++++++++++++ .../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, 378 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..fbe0b2d9f7a23 100644 --- a/clang-tools-extra/clang-tidy/modernize/MakeUniqueCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/MakeUniqueCheck.cpp @@ -14,14 +14,14 @@ 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..16d84c0acc731 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -121,6 +121,17 @@ 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 + :doc:`modernize-make-shared <clang-tidy/checks/modernize/make-shared>` and + :doc:`modernize-make-unique <clang-tidy/checks/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 +216,15 @@ 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. + +- 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 + `MakeSmartPtrType` to specify the smart pointer type to match. + - 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..2839c30e4f3f3 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/misc/make-smart-ptr.rst @@ -0,0 +1,63 @@ +.. 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 +:option:`MakeSmartPtrType` and :option:`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 string. + +.. option:: MakeSmartPtrFunctionHeader + + A string specifying the corresponding header of the factory function. + Default is empty string. + +.. option:: MakeSmartPtrType + + A string specifying the smart pointer type to match. This option must be + set for the check to work. Default is empty string. + +.. option:: IncludeStyle + + A string specifying which include-style is used, `llvm` or `google`. Default + is `llvm`. This option can also be set globally via the + ``IncludeStyle`` global option. + +.. 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..9b50aabd31930 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..3d6de34905b21 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
