https://github.com/hjanuschka updated https://github.com/llvm/llvm-project/pull/117529
>From 9466fb73adfb050e9eac426459c18a7a5bca1982 Mon Sep 17 00:00:00 2001 From: Helmut Januschka <hel...@januschka.com> Date: Mon, 25 Nov 2024 09:59:21 +0100 Subject: [PATCH 1/2] WIP: [clang-tidy] Add SmartPtrName to MakeSmartPtrCheck for flexible type matching Introduced a `SmartPtrName` field in `MakeSmartPtrCheck` to allow matching on other smart pointer types, such as `base::scoped_refptr`, in addition to `std::shared_ptr`. This enables more versatile usage of the check without duplicating matcher logic. --- clang-tools-extra/clang-tidy/modernize/MakeSharedCheck.cpp | 5 +++-- clang-tools-extra/clang-tidy/modernize/MakeSharedCheck.h | 3 +++ .../clang-tidy/modernize/MakeSmartPtrCheck.cpp | 6 +++--- clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h | 1 + .../docs/clang-tidy/checks/modernize/make-shared.rst | 6 ++++++ 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/MakeSharedCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MakeSharedCheck.cpp index 69f7d9f69eeed0..34009046fec6ae 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"), + MakeSmartPtrType(Options.get("MakeSmartPtrType", "::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/MakeSharedCheck.h b/clang-tools-extra/clang-tidy/modernize/MakeSharedCheck.h index caaf4ae403c34f..932796e3a147f1 100644 --- a/clang-tools-extra/clang-tidy/modernize/MakeSharedCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/MakeSharedCheck.h @@ -26,6 +26,9 @@ namespace clang::tidy::modernize { /// For the user-facing documentation see: /// http://clang.llvm.org/extra/clang-tidy/checks/modernize/make-shared.html class MakeSharedCheck : public MakeSmartPtrCheck { +private: + const StringRef MakeSmartPtrType; + public: MakeSharedCheck(StringRef Name, ClangTidyContext *Context); diff --git a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp index d1d7e9dcfa9c0d..3f77e6727d19f8 100644 --- a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp @@ -46,6 +46,7 @@ MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context, areDiagsSelfContained()), MakeSmartPtrFunctionHeader( Options.get("MakeSmartPtrFunctionHeader", "<memory>")), + MakeSmartPtrType(Options.get("MakeSmartPtrType", "::std::shared_ptr")), MakeSmartPtrFunctionName( Options.get("MakeSmartPtrFunction", MakeSmartPtrFunctionName)), IgnoreMacros(Options.getLocalOrGlobal("IgnoreMacros", true)), @@ -55,6 +56,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", @@ -115,7 +117,6 @@ void MakeSmartPtrCheck::check(const MatchFinder::MatchResult &Result) { // 'smart_ptr' refers to 'std::shared_ptr' or 'std::unique_ptr' or other // pointer, 'make_smart_ptr' refers to 'std::make_shared' or // 'std::make_unique' or other function that creates smart_ptr. - SourceManager &SM = *Result.SourceManager; const auto *Construct = Result.Nodes.getNodeAs<CXXConstructExpr>(ConstructorCall); @@ -361,8 +362,7 @@ bool MakeSmartPtrCheck::replaceNew(DiagnosticBuilder &Diag, Diag << FixItHint::CreateRemoval( SourceRange(NewStart, InitRange.getBegin())); Diag << FixItHint::CreateRemoval(SourceRange(InitRange.getEnd(), NewEnd)); - } - else { + } else { // New array expression with default/value initialization: // smart_ptr<Foo[]>(new int[5]()); // smart_ptr<Foo[]>(new Foo[5]()); diff --git a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h index 02374dc06d9be5..c4b407e5090656 100644 --- a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h @@ -46,6 +46,7 @@ class MakeSmartPtrCheck : public ClangTidyCheck { private: utils::IncludeInserter Inserter; const StringRef MakeSmartPtrFunctionHeader; + const StringRef MakeSmartPtrType; const StringRef MakeSmartPtrFunctionName; const bool IgnoreMacros; const bool IgnoreDefaultInitialization; 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 9c1fceaa060002..31d3de7a7893f3 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,12 @@ Options A string specifying the corresponding header of make-shared-ptr function. Default is `memory`. + +.. option:: MakeSmartPtrType + + A string specifying the corresponding pointer type. + Default is `::std::shared_ptr`. + .. option:: IncludeStyle A string specifying which include-style is used, `llvm` or `google`. Default >From bf9292eb4f758ba22feedf56a3de47e8234ca3d2 Mon Sep 17 00:00:00 2001 From: Helmut Januschka <hel...@januschka.com> Date: Mon, 25 Nov 2024 11:40:50 +0100 Subject: [PATCH 2/2] up --- .../modernize/make-shared-ptr-name.cpp | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/make-shared-ptr-name.cpp 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 00000000000000..0be12a47c0db41 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/make-shared-ptr-name.cpp @@ -0,0 +1,142 @@ +// 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: -- -std=c++11 -nostdinc++ + +namespace base { + +using nullptr_t = decltype(nullptr); + +template <typename T> +struct remove_extent { typedef T type; }; + +template <typename T> +struct remove_reference { typedef T type; }; + +template <typename T> +class scoped_refptr { +public: + typedef T element_type; + typedef T* pointer; + typedef element_type& reference; + + // Default constructors + constexpr scoped_refptr() noexcept : ptr_(nullptr) {} + constexpr scoped_refptr(nullptr_t) noexcept : ptr_(nullptr) {} + + // Constructors from raw pointer + explicit scoped_refptr(T* p) noexcept : ptr_(p) {} + scoped_refptr(T* p, bool) noexcept : ptr_(p) {} // Special constructor for temporaries + + // Copy constructors + scoped_refptr(const scoped_refptr& r) noexcept : ptr_(r.ptr_) {} + template<typename U> + scoped_refptr(const scoped_refptr<U>& r) noexcept : ptr_(r.get()) {} + + // Move constructors + scoped_refptr(scoped_refptr&& r) noexcept : ptr_(r.ptr_) { + r.ptr_ = nullptr; + } + template<typename U> + scoped_refptr(scoped_refptr<U>&& r) noexcept : ptr_(r.get()) { + r.reset(); + } + + // Assignment operators + scoped_refptr& operator=(const scoped_refptr& r) noexcept { + ptr_ = r.ptr_; + return *this; + } + template<typename U> + scoped_refptr& operator=(const scoped_refptr<U>& r) noexcept { + ptr_ = r.get(); + return *this; + } + + scoped_refptr& operator=(scoped_refptr&& r) noexcept { + ptr_ = r.ptr_; + r.ptr_ = nullptr; + return *this; + } + template<typename U> + scoped_refptr& operator=(scoped_refptr<U>&& r) noexcept { + ptr_ = r.get(); + r.reset(); + return *this; + } + + void reset(T* p = nullptr) noexcept { + ptr_ = p; + } + + void swap(scoped_refptr& r) noexcept { + T* tmp = ptr_; + ptr_ = r.ptr_; + r.ptr_ = tmp; + } + + // Observers + T* get() const noexcept { return ptr_; } + T& operator*() const noexcept { return *ptr_; } + T* operator->() const noexcept { return ptr_; } + explicit operator bool() const noexcept { return ptr_ != nullptr; } + + ~scoped_refptr() { } + +private: + element_type* ptr_; +}; + +// Non-member functions +template<class T> +void swap(scoped_refptr<T>& a, scoped_refptr<T>& b) noexcept { + a.swap(b); +} + +template<class T, class U> +bool operator==(const scoped_refptr<T>& a, const scoped_refptr<U>& b) noexcept { + return a.get() == b.get(); +} + +template<class T> +bool operator==(const scoped_refptr<T>& a, nullptr_t) noexcept { + return !a; +} + +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) : Base(0, 0) {} +}; + +void basic() { + // Direct constructor calls - not covered by this check + base::scoped_refptr<int> P1(new int()); + base::scoped_refptr<Base> basePtr(new Base()); + + // Reset calls + P1.reset(new int()); + // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use base::MakeRefCounted instead + // CHECK-FIXES: P1 = base::MakeRefCounted<int>(); + + basePtr.reset(new Derived()); + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use base::MakeRefCounted instead + // CHECK-FIXES: basePtr = 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>(); +} \ No newline at end of file _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits