[clang-tools-extra] [clang-tidy] Add bugprone-smartptr-reset-ambiguous-call check (PR #121291)

Baranov Victor via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 17 12:23:29 PST 2025


https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/121291

>From 42e03bb9cc9bd815476b0a3f06ac5f58826e3708 Mon Sep 17 00:00:00 2001
From: Victor Baranov <bar.victor.2002 at gmail.com>
Date: Fri, 31 Jan 2025 19:29:05 +0300
Subject: [PATCH 1/4] [clang-tidy] add new check bugprone-reset-ambiguous-call

---
 .../bugprone/BugproneTidyModule.cpp           |   3 +
 .../clang-tidy/bugprone/CMakeLists.txt        |   1 +
 .../SmartptrResetAmbiguousCallCheck.cpp       | 146 +++++++++++
 .../SmartptrResetAmbiguousCallCheck.h         |  37 +++
 clang-tools-extra/docs/ReleaseNotes.rst       |   6 +
 .../smartptr-reset-ambiguous-call.rst         |  47 ++++
 .../docs/clang-tidy/checks/list.rst           |   1 +
 ...r-reset-ambiguous-call-custom-pointers.cpp |  72 ++++++
 .../smartptr-reset-ambiguous-call.cpp         | 239 ++++++++++++++++++
 9 files changed, 552 insertions(+)
 create mode 100644 clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.cpp
 create mode 100644 clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.h
 create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/smartptr-reset-ambiguous-call.rst
 create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call-custom-pointers.cpp
 create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call.cpp

diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
index c5f0b5b28418f..a01d0e384ab73 100644
--- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
@@ -64,6 +64,7 @@
 #include "SignedCharMisuseCheck.h"
 #include "SizeofContainerCheck.h"
 #include "SizeofExpressionCheck.h"
+#include "SmartptrResetAmbiguousCallCheck.h"
 #include "SpuriouslyWakeUpFunctionsCheck.h"
 #include "StandaloneEmptyCheck.h"
 #include "StringConstructorCheck.h"
@@ -207,6 +208,8 @@ class BugproneModule : public ClangTidyModule {
         "bugprone-sizeof-container");
     CheckFactories.registerCheck<SizeofExpressionCheck>(
         "bugprone-sizeof-expression");
+    CheckFactories.registerCheck<SmartptrResetAmbiguousCallCheck>(
+        "bugprone-smartptr-reset-ambiguous-call");
     CheckFactories.registerCheck<SpuriouslyWakeUpFunctionsCheck>(
         "bugprone-spuriously-wake-up-functions");
     CheckFactories.registerCheck<StandaloneEmptyCheck>(
diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
index e8309c68b7fca..7fd6f4994f537 100644
--- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
@@ -65,6 +65,7 @@ add_clang_library(clangTidyBugproneModule STATIC
   SizeofContainerCheck.cpp
   SizeofExpressionCheck.cpp
   SmartPtrArrayMismatchCheck.cpp
+  SmartptrResetAmbiguousCallCheck.cpp
   SpuriouslyWakeUpFunctionsCheck.cpp
   StandaloneEmptyCheck.cpp
   StringConstructorCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.cpp
new file mode 100644
index 0000000000000..326a5665179d7
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.cpp
@@ -0,0 +1,146 @@
+//===--- SmartptrResetAmbiguousCallCheck.cpp - clang-tidy -----------------===//
+//
+// 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 "SmartptrResetAmbiguousCallCheck.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::bugprone {
+
+namespace {
+
+AST_MATCHER_P(CallExpr, everyArgumentMatches,
+              ast_matchers::internal::Matcher<Expr>, InnerMatcher) {
+  for (const auto *Arg : Node.arguments()) {
+    if (!InnerMatcher.matches(*Arg, Finder, Builder))
+      return false;
+  }
+
+  return true;
+}
+
+AST_MATCHER(CXXMethodDecl, hasOnlyDefaultParameters) {
+  for (const auto *Param : Node.parameters()) {
+    if (!Param->hasDefaultArg())
+      return false;
+  }
+
+  return true;
+}
+
+const auto DefaultSmartPointers = "::std::shared_ptr;::std::unique_ptr";
+} // namespace
+
+SmartptrResetAmbiguousCallCheck::SmartptrResetAmbiguousCallCheck(
+    StringRef Name, ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context),
+      SmartPointers(utils::options::parseStringList(
+          Options.get("SmartPointers", DefaultSmartPointers))) {}
+
+void SmartptrResetAmbiguousCallCheck::storeOptions(
+    ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "SmartPointers",
+                utils::options::serializeStringList(SmartPointers));
+}
+
+void SmartptrResetAmbiguousCallCheck::registerMatchers(MatchFinder *Finder) {
+  const auto IsSmartptr = hasAnyName(SmartPointers);
+
+  const auto ResetMethod =
+      cxxMethodDecl(hasName("reset"), hasOnlyDefaultParameters());
+
+  const auto TypeWithReset =
+      anyOf(cxxRecordDecl(hasMethod(ResetMethod)),
+            classTemplateSpecializationDecl(
+                hasSpecializedTemplate(classTemplateDecl(has(ResetMethod)))));
+
+  const auto SmartptrWithBugproneReset = classTemplateSpecializationDecl(
+      IsSmartptr,
+      hasTemplateArgument(
+          0, templateArgument(refersToType(hasUnqualifiedDesugaredType(
+                 recordType(hasDeclaration(TypeWithReset)))))));
+
+  // Find a.reset() calls
+  Finder->addMatcher(
+      cxxMemberCallExpr(callee(memberExpr(member(hasName("reset")))),
+                        everyArgumentMatches(cxxDefaultArgExpr()),
+                        on(expr(hasType(SmartptrWithBugproneReset))))
+          .bind("smartptrResetCall"),
+      this);
+
+  // Find a->reset() calls
+  Finder->addMatcher(
+      cxxMemberCallExpr(
+          callee(memberExpr(
+              member(ResetMethod),
+              hasObjectExpression(
+                  cxxOperatorCallExpr(
+                      hasOverloadedOperatorName("->"),
+                      hasArgument(
+                          0, expr(hasType(
+                                 classTemplateSpecializationDecl(IsSmartptr)))))
+                      .bind("OpCall")))),
+          everyArgumentMatches(cxxDefaultArgExpr()))
+          .bind("objectResetCall"),
+      this);
+}
+
+void SmartptrResetAmbiguousCallCheck::check(
+    const MatchFinder::MatchResult &Result) {
+
+  if (const auto *SmartptrResetCall =
+          Result.Nodes.getNodeAs<CXXMemberCallExpr>("smartptrResetCall")) {
+    const auto *Member = cast<MemberExpr>(SmartptrResetCall->getCallee());
+
+    diag(SmartptrResetCall->getBeginLoc(),
+         "be explicit when calling 'reset()' on a smart pointer with a "
+         "pointee that has a 'reset()' method");
+
+    diag(SmartptrResetCall->getBeginLoc(), "assign the pointer to 'nullptr'",
+         DiagnosticIDs::Note)
+        << FixItHint::CreateReplacement(
+               SourceRange(Member->getOperatorLoc(),
+                           Member->getOperatorLoc().getLocWithOffset(0)),
+               " =")
+        << FixItHint::CreateReplacement(
+               SourceRange(Member->getMemberLoc(),
+                           SmartptrResetCall->getEndLoc()),
+               " nullptr");
+    return;
+  }
+
+  if (const auto *ObjectResetCall =
+          Result.Nodes.getNodeAs<CXXMemberCallExpr>("objectResetCall")) {
+    const auto *Arrow = Result.Nodes.getNodeAs<CXXOperatorCallExpr>("OpCall");
+
+    const CharSourceRange SmartptrSourceRange =
+        Lexer::getAsCharRange(Arrow->getArg(0)->getSourceRange(),
+                              *Result.SourceManager, getLangOpts());
+
+    diag(ObjectResetCall->getBeginLoc(),
+         "be explicit when calling 'reset()' on a pointee of a smart pointer");
+
+    diag(ObjectResetCall->getBeginLoc(),
+         "use dereference to call 'reset' method of the pointee",
+         DiagnosticIDs::Note)
+        << FixItHint::CreateInsertion(SmartptrSourceRange.getBegin(), "(*")
+        << FixItHint::CreateInsertion(SmartptrSourceRange.getEnd(), ")")
+        << FixItHint::CreateReplacement(
+               CharSourceRange::getCharRange(
+                   Arrow->getOperatorLoc(),
+                   Arrow->getOperatorLoc().getLocWithOffset(2)),
+               ".");
+  }
+}
+
+} // namespace clang::tidy::bugprone
diff --git a/clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.h b/clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.h
new file mode 100644
index 0000000000000..474bcf1804581
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.h
@@ -0,0 +1,37 @@
+//===--- SmartptrResetAmbiguousCallCheck.h - clang-tidy ---------*- C++ -*-===//
+//
+// 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_BUGPRONE_SMARTPTRRESETAMBIGUOUSCALLCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SMARTPTRRESETAMBIGUOUSCALLCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::bugprone {
+
+/// Finds potentially erroneous calls to 'reset' method on smart pointers when
+/// the pointee type also has a 'reset' method
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone/smartptr-reset-ambiguous-call.html
+class SmartptrResetAmbiguousCallCheck : public ClangTidyCheck {
+public:
+  SmartptrResetAmbiguousCallCheck(StringRef Name, ClangTidyContext *Context);
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+  void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+    return LangOpts.CPlusPlus;
+  }
+
+private:
+  const std::vector<StringRef> SmartPointers;
+};
+
+} // namespace clang::tidy::bugprone
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SMARTPTRRESETAMBIGUOUSCALLCHECK_H
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 3bddeeda06e06..ef48acf958c9e 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -91,6 +91,12 @@ Improvements to clang-tidy
 New checks
 ^^^^^^^^^^
 
+- New :doc:`bugprone-smartptr-reset-ambiguous-call
+  <clang-tidy/checks/bugprone/smartptr-reset-ambiguous-call>` check.
+
+  Finds potentially erroneous calls to ``reset`` method on smart pointers when
+  the pointee type also has a ``reset`` method.
+
 New check aliases
 ^^^^^^^^^^^^^^^^^
 
diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/smartptr-reset-ambiguous-call.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/smartptr-reset-ambiguous-call.rst
new file mode 100644
index 0000000000000..263105e420813
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/smartptr-reset-ambiguous-call.rst
@@ -0,0 +1,47 @@
+.. title:: clang-tidy - bugprone-smartptr-reset-ambiguous-call
+
+bugprone-smartptr-reset-ambiguous-call
+======================================
+
+Finds potentially erroneous calls to ``reset`` method on smart pointers when
+the pointee type also has a ``reset`` method. Having a ``reset`` method in
+both classes makes it easy to accidentally make the pointer null when
+intending to reset the underlying object.
+
+.. code-block:: c++
+
+  struct Resettable {
+    void reset() { /* Own reset logic */ }
+  };
+
+  auto ptr = std::make_unique<Resettable>();
+
+  ptr->reset();  // Calls underlying reset method
+  ptr.reset();   // Makes the pointer null
+
+Both calls are valid C++ code, but the second one might not be what the
+developer intended, as it destroys the pointed-to object rather than resetting
+its state. It's easy to make such a typo because the difference between
+``.`` and ``->`` is really small.
+
+The recommended approach is to make the intent explicit by using either member
+access or direct assignment:
+
+.. code-block:: c++
+
+  std::unique_ptr<Resettable> ptr = std::make_unique<Resettable>();
+
+  (*ptr).reset();  // Clearly calls underlying reset method
+  ptr = nullptr;   // Clearly makes the pointer null
+
+The default smart pointers that are considered are ``std::unique_ptr``,
+``std::shared_ptr``. To specify other smart pointers or other classes use the
+:option:`SmartPointers` option.
+
+Options
+-------
+
+.. option:: SmartPointers
+
+    Semicolon-separated list of class names of custom smart pointers.
+    Default value is `::std::unique_ptr;::std::shared_ptr`.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index 7b9b905ef7671..ec6dd26b78977 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -132,6 +132,7 @@ Clang-Tidy Checks
    :doc:`bugprone-signed-char-misuse <bugprone/signed-char-misuse>`,
    :doc:`bugprone-sizeof-container <bugprone/sizeof-container>`,
    :doc:`bugprone-sizeof-expression <bugprone/sizeof-expression>`,
+   :doc:`bugprone-smartptr-reset-ambiguous-call <bugprone/smartptr-reset-ambiguous-call>`, "Yes"
    :doc:`bugprone-spuriously-wake-up-functions <bugprone/spuriously-wake-up-functions>`,
    :doc:`bugprone-standalone-empty <bugprone/standalone-empty>`, "Yes"
    :doc:`bugprone-string-constructor <bugprone/string-constructor>`, "Yes"
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call-custom-pointers.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call-custom-pointers.cpp
new file mode 100644
index 0000000000000..bcb2498bd2043
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call-custom-pointers.cpp
@@ -0,0 +1,72 @@
+// RUN: %check_clang_tidy %s bugprone-smartptr-reset-ambiguous-call %t \
+// RUN: -config='{CheckOptions: \
+// RUN:  {bugprone-smartptr-reset-ambiguous-call.SmartPointers: "::std::unique_ptr;boost::shared_ptr"}}' \
+// RUN: --fix-notes --
+
+namespace std {
+
+template <typename T>
+struct unique_ptr {
+  T& operator*() const;
+  T* operator->() const;
+  void reset(T* p = nullptr);
+};
+
+template <typename T>
+struct shared_ptr {
+  T& operator*() const;
+  T* operator->() const;
+  void reset();
+  void reset(T*);
+};
+
+} // namespace std
+
+namespace boost {
+
+template <typename T>
+struct shared_ptr {
+  T& operator*() const;
+  T* operator->() const;
+  void reset();
+};
+
+} // namespace boost
+
+struct Resettable {
+  void reset();
+  void doSomething();
+};
+
+void Positive() {
+  std::unique_ptr<Resettable> u;
+  u.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
+  // CHECK-FIXES: u = nullptr;
+  u->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
+  // CHECK-FIXES: (*u).reset();
+
+  boost::shared_ptr<Resettable> s;
+  s.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
+  // CHECK-FIXES: s = nullptr;
+  s->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
+  // CHECK-FIXES: (*s).reset();
+}
+
+void Negative() {
+  std::shared_ptr<Resettable> s_ptr;
+  s_ptr.reset();
+  s_ptr->reset();
+  s_ptr->doSomething();
+
+  std::unique_ptr<Resettable> u_ptr;
+  u_ptr.reset(nullptr);
+  u_ptr->doSomething();
+}
\ No newline at end of file
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call.cpp
new file mode 100644
index 0000000000000..4227733404f6b
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call.cpp
@@ -0,0 +1,239 @@
+// RUN: %check_clang_tidy %s bugprone-smartptr-reset-ambiguous-call %t --fix-notes --
+
+namespace std {
+
+template <typename T>
+struct unique_ptr {
+  T& operator*() const;
+  T* operator->() const;
+  void reset(T* p = nullptr);
+};
+
+template <typename T>
+struct shared_ptr {
+  T& operator*() const;
+  T* operator->() const;
+  void reset();
+  void reset(T*);
+};
+
+} // namespace std
+
+struct Resettable {
+  void reset();
+  void doSomething();
+};
+
+struct ResettableWithParam {
+  void reset(int a);
+  void doSomething();
+};
+
+struct ResettableWithDefaultParams {
+  void reset(int a = 0, double b = 0.0);
+  void doSomething();
+};
+
+struct NonResettable {
+  void doSomething();
+};
+
+void Positive() {
+  std::unique_ptr<Resettable> u;
+  u.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
+  // CHECK-FIXES: u = nullptr;
+  u->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
+  // CHECK-FIXES: (*u).reset();
+
+  std::shared_ptr<Resettable> s;
+  s.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
+  // CHECK-FIXES: s = nullptr;
+  s->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
+  // CHECK-FIXES: (*s).reset();
+
+  std::unique_ptr<std::unique_ptr<int>> uu_ptr;
+  uu_ptr.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
+  // CHECK-FIXES: uu_ptr = nullptr;
+  uu_ptr->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
+  // CHECK-FIXES: (*uu_ptr).reset();
+
+  std::unique_ptr<std::shared_ptr<int>> su_ptr;
+  su_ptr.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
+  // CHECK-FIXES: su_ptr = nullptr;
+  su_ptr->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
+  // CHECK-FIXES: (*su_ptr).reset();
+
+  std::unique_ptr<ResettableWithDefaultParams> rd;
+  rd.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
+  // CHECK-FIXES: rd = nullptr;
+  rd->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
+  // CHECK-FIXES: (*rd).reset();
+
+  std::unique_ptr<std::shared_ptr<std::unique_ptr<Resettable>>> nested_ptr;
+  nested_ptr.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
+  // CHECK-FIXES: nested_ptr = nullptr;
+  nested_ptr->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
+  // CHECK-FIXES: (*nested_ptr).reset();
+  (*nested_ptr).reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
+  // CHECK-FIXES: (*nested_ptr) = nullptr;
+  (*nested_ptr)->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
+  // CHECK-FIXES: (*(*nested_ptr)).reset();
+  (**nested_ptr).reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
+  // CHECK-FIXES: (**nested_ptr) = nullptr;
+  (**nested_ptr)->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
+  // CHECK-FIXES: (*(**nested_ptr)).reset();
+}
+
+void Negative() {
+  std::unique_ptr<Resettable> u_ptr;
+  u_ptr.reset(nullptr);
+  u_ptr->doSomething();
+
+  std::shared_ptr<Resettable> s_ptr;
+  s_ptr.reset(nullptr);
+  s_ptr->doSomething();
+  
+  Resettable* raw_ptr;
+  raw_ptr->reset();
+  raw_ptr->doSomething();
+
+  Resettable resettable;
+  resettable.reset();
+  resettable.doSomething();
+  
+  std::unique_ptr<ResettableWithParam> u_ptr_param;
+  u_ptr_param.reset();
+  u_ptr_param.reset(nullptr);
+  u_ptr_param->reset(0);
+
+  std::unique_ptr<NonResettable> u_ptr_no_reset;
+  u_ptr_no_reset.reset();
+
+  std::shared_ptr<ResettableWithParam> s_ptr_param;
+  s_ptr_param.reset();
+  s_ptr_param->reset(0);
+  s_ptr_param->doSomething();
+
+  std::shared_ptr<NonResettable> s_ptr_no_reset;
+  s_ptr_no_reset.reset();
+
+  std::unique_ptr<ResettableWithDefaultParams> u_ptr_default_params;
+  u_ptr_default_params.reset(nullptr);
+  u_ptr_default_params->reset(1);
+  u_ptr_default_params->reset(1, 2.0);
+}
+
+template <typename T>
+void TemplatePositiveTest() {
+  std::unique_ptr<T> u_ptr;
+
+  u_ptr.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
+  // CHECK-FIXES: u_ptr = nullptr;
+  u_ptr->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
+  // CHECK-FIXES: (*u_ptr).reset();
+
+  std::shared_ptr<T> s_ptr;
+  s_ptr.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
+  // CHECK-FIXES: s_ptr = nullptr;
+  s_ptr->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
+  // CHECK-FIXES: (*s_ptr).reset();
+}
+
+template <typename T>
+void TemplatNegativeTestTypeWithReset() {
+  std::unique_ptr<T> u_ptr;
+  u_ptr.reset();
+  u_ptr->reset(0);
+
+  std::shared_ptr<T> s_ptr;
+  s_ptr.reset();
+  s_ptr->reset(0);
+}
+
+template <typename T>
+void TemplatNegativeTestTypeWithoutReset() {
+  std::unique_ptr<T> u_ptr;
+  u_ptr.reset();
+
+  std::unique_ptr<T> s_ptr;
+  s_ptr.reset();
+}
+
+void instantiate() {
+  TemplatePositiveTest<Resettable>();
+  TemplatePositiveTest<std::unique_ptr<int>>();
+  TemplatePositiveTest<std::shared_ptr<int>>();
+  TemplatNegativeTestTypeWithReset<ResettableWithParam>();
+  TemplatNegativeTestTypeWithoutReset<NonResettable>();
+}
+
+struct S {
+  void foo() {
+    u_ptr.reset();
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
+    // CHECK-MESSAGES: :[[@LINE-2]]:5: note: assign the pointer to 'nullptr'
+    // CHECK-FIXES: u_ptr = nullptr;
+    u_ptr->reset();
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
+    // CHECK-MESSAGES: :[[@LINE-2]]:5: note: use dereference to call 'reset' method of the pointee
+    // CHECK-FIXES: (*u_ptr).reset();
+    u_ptr.reset(nullptr);
+    u_ptr->doSomething();
+
+    s_ptr.reset();
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
+    // CHECK-MESSAGES: :[[@LINE-2]]:5: note: assign the pointer to 'nullptr'
+    // CHECK-FIXES: s_ptr = nullptr;
+    s_ptr->reset();
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
+    // CHECK-MESSAGES: :[[@LINE-2]]:5: note: use dereference to call 'reset' method of the pointee
+    // CHECK-FIXES: (*s_ptr).reset();
+    s_ptr.reset(nullptr);
+
+    ptr.reset();
+  }
+
+  std::unique_ptr<Resettable> u_ptr;
+  std::unique_ptr<std::shared_ptr<int>> s_ptr;
+  std::unique_ptr<NonResettable> ptr;
+};

>From 851afcc804ad3c55e3bd837e6dadeb8166c4c6ad Mon Sep 17 00:00:00 2001
From: Victor Baranov <bar.victor.2002 at gmail.com>
Date: Fri, 31 Jan 2025 19:33:02 +0300
Subject: [PATCH 2/4] [clang-tidy] add newline in test file

---
 .../bugprone/smartptr-reset-ambiguous-call-custom-pointers.cpp  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call-custom-pointers.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call-custom-pointers.cpp
index bcb2498bd2043..2b8944c39619d 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call-custom-pointers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call-custom-pointers.cpp
@@ -69,4 +69,4 @@ void Negative() {
   std::unique_ptr<Resettable> u_ptr;
   u_ptr.reset(nullptr);
   u_ptr->doSomething();
-}
\ No newline at end of file
+}

>From 21a6fdce045ed7d88fff38812fd568a4342ed845 Mon Sep 17 00:00:00 2001
From: Victor Baranov <bar.victor.2002 at gmail.com>
Date: Mon, 17 Feb 2025 12:00:06 +0300
Subject: [PATCH 3/4] [clang-tidy] renamed
 bugprone-smartptr-reset-ambiguous-call to
 readability-ambiguous-smartptr-reset-call, fixed pr comments

---
 .../bugprone/BugproneTidyModule.cpp           |   3 -
 .../clang-tidy/bugprone/CMakeLists.txt        |   1 -
 .../AmbiguousSmartptrResetCallCheck.cpp}      |  29 ++-
 .../AmbiguousSmartptrResetCallCheck.h}        |  18 +-
 .../clang-tidy/readability/CMakeLists.txt     |   1 +
 .../readability/ReadabilityTidyModule.cpp     |   3 +
 clang-tools-extra/docs/ReleaseNotes.rst       |   4 +-
 .../docs/clang-tidy/checks/list.rst           |   2 +-
 .../ambiguous-smartptr-reset-call.rst}        |  15 +-
 ...r-reset-ambiguous-call-custom-pointers.cpp |  72 ------
 .../smartptr-reset-ambiguous-call.cpp         | 239 ------------------
 ...us-smartptr-reset-call-custom-pointers.cpp |  68 +++++
 .../ambiguous-smartptr-reset-call.cpp         | 239 ++++++++++++++++++
 13 files changed, 347 insertions(+), 347 deletions(-)
 rename clang-tools-extra/clang-tidy/{bugprone/SmartptrResetAmbiguousCallCheck.cpp => readability/AmbiguousSmartptrResetCallCheck.cpp} (83%)
 rename clang-tools-extra/clang-tidy/{bugprone/SmartptrResetAmbiguousCallCheck.h => readability/AmbiguousSmartptrResetCallCheck.h} (59%)
 rename clang-tools-extra/docs/clang-tidy/checks/{bugprone/smartptr-reset-ambiguous-call.rst => readability/ambiguous-smartptr-reset-call.rst} (70%)
 delete mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call-custom-pointers.cpp
 delete mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call.cpp
 create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/ambiguous-smartptr-reset-call-custom-pointers.cpp
 create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/ambiguous-smartptr-reset-call.cpp

diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
index a01d0e384ab73..c5f0b5b28418f 100644
--- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
@@ -64,7 +64,6 @@
 #include "SignedCharMisuseCheck.h"
 #include "SizeofContainerCheck.h"
 #include "SizeofExpressionCheck.h"
-#include "SmartptrResetAmbiguousCallCheck.h"
 #include "SpuriouslyWakeUpFunctionsCheck.h"
 #include "StandaloneEmptyCheck.h"
 #include "StringConstructorCheck.h"
@@ -208,8 +207,6 @@ class BugproneModule : public ClangTidyModule {
         "bugprone-sizeof-container");
     CheckFactories.registerCheck<SizeofExpressionCheck>(
         "bugprone-sizeof-expression");
-    CheckFactories.registerCheck<SmartptrResetAmbiguousCallCheck>(
-        "bugprone-smartptr-reset-ambiguous-call");
     CheckFactories.registerCheck<SpuriouslyWakeUpFunctionsCheck>(
         "bugprone-spuriously-wake-up-functions");
     CheckFactories.registerCheck<StandaloneEmptyCheck>(
diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
index 7fd6f4994f537..e8309c68b7fca 100644
--- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
@@ -65,7 +65,6 @@ add_clang_library(clangTidyBugproneModule STATIC
   SizeofContainerCheck.cpp
   SizeofExpressionCheck.cpp
   SmartPtrArrayMismatchCheck.cpp
-  SmartptrResetAmbiguousCallCheck.cpp
   SpuriouslyWakeUpFunctionsCheck.cpp
   StandaloneEmptyCheck.cpp
   StringConstructorCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.cpp b/clang-tools-extra/clang-tidy/readability/AmbiguousSmartptrResetCallCheck.cpp
similarity index 83%
rename from clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.cpp
rename to clang-tools-extra/clang-tidy/readability/AmbiguousSmartptrResetCallCheck.cpp
index 326a5665179d7..86dc9a33c0755 100644
--- a/clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/AmbiguousSmartptrResetCallCheck.cpp
@@ -1,4 +1,4 @@
-//===--- SmartptrResetAmbiguousCallCheck.cpp - clang-tidy -----------------===//
+//===--- AmbiguousSmartptrResetCallCheck.cpp - clang-tidy -----------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "SmartptrResetAmbiguousCallCheck.h"
+#include "AmbiguousSmartptrResetCallCheck.h"
 #include "../utils/OptionsUtils.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
@@ -15,7 +15,7 @@
 
 using namespace clang::ast_matchers;
 
-namespace clang::tidy::bugprone {
+namespace clang::tidy::readability {
 
 namespace {
 
@@ -41,19 +41,19 @@ AST_MATCHER(CXXMethodDecl, hasOnlyDefaultParameters) {
 const auto DefaultSmartPointers = "::std::shared_ptr;::std::unique_ptr";
 } // namespace
 
-SmartptrResetAmbiguousCallCheck::SmartptrResetAmbiguousCallCheck(
+AmbiguousSmartptrResetCallCheck::AmbiguousSmartptrResetCallCheck(
     StringRef Name, ClangTidyContext *Context)
     : ClangTidyCheck(Name, Context),
       SmartPointers(utils::options::parseStringList(
           Options.get("SmartPointers", DefaultSmartPointers))) {}
 
-void SmartptrResetAmbiguousCallCheck::storeOptions(
+void AmbiguousSmartptrResetCallCheck::storeOptions(
     ClangTidyOptions::OptionMap &Opts) {
   Options.store(Opts, "SmartPointers",
                 utils::options::serializeStringList(SmartPointers));
 }
 
-void SmartptrResetAmbiguousCallCheck::registerMatchers(MatchFinder *Finder) {
+void AmbiguousSmartptrResetCallCheck::registerMatchers(MatchFinder *Finder) {
   const auto IsSmartptr = hasAnyName(SmartPointers);
 
   const auto ResetMethod =
@@ -95,7 +95,7 @@ void SmartptrResetAmbiguousCallCheck::registerMatchers(MatchFinder *Finder) {
       this);
 }
 
-void SmartptrResetAmbiguousCallCheck::check(
+void AmbiguousSmartptrResetCallCheck::check(
     const MatchFinder::MatchResult &Result) {
 
   if (const auto *SmartptrResetCall =
@@ -103,10 +103,11 @@ void SmartptrResetAmbiguousCallCheck::check(
     const auto *Member = cast<MemberExpr>(SmartptrResetCall->getCallee());
 
     diag(SmartptrResetCall->getBeginLoc(),
-         "be explicit when calling 'reset()' on a smart pointer with a "
-         "pointee that has a 'reset()' method");
+         "ambiguous call to 'reset()' on a smart pointer with pointee that "
+         "also has a 'reset()' method, prefer more explicit approach");
 
-    diag(SmartptrResetCall->getBeginLoc(), "assign the pointer to 'nullptr'",
+    diag(SmartptrResetCall->getBeginLoc(),
+         "consider assigning the pointer to 'nullptr' here",
          DiagnosticIDs::Note)
         << FixItHint::CreateReplacement(
                SourceRange(Member->getOperatorLoc(),
@@ -128,10 +129,12 @@ void SmartptrResetAmbiguousCallCheck::check(
                               *Result.SourceManager, getLangOpts());
 
     diag(ObjectResetCall->getBeginLoc(),
-         "be explicit when calling 'reset()' on a pointee of a smart pointer");
+         "ambiguous call to 'reset()' on a pointee of a smart pointer, prefer "
+         "more explicit approach");
 
     diag(ObjectResetCall->getBeginLoc(),
-         "use dereference to call 'reset' method of the pointee",
+         "consider dereferencing smart pointer to call 'reset' method "
+         "of the pointee here",
          DiagnosticIDs::Note)
         << FixItHint::CreateInsertion(SmartptrSourceRange.getBegin(), "(*")
         << FixItHint::CreateInsertion(SmartptrSourceRange.getEnd(), ")")
@@ -143,4 +146,4 @@ void SmartptrResetAmbiguousCallCheck::check(
   }
 }
 
-} // namespace clang::tidy::bugprone
+} // namespace clang::tidy::readability
diff --git a/clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.h b/clang-tools-extra/clang-tidy/readability/AmbiguousSmartptrResetCallCheck.h
similarity index 59%
rename from clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.h
rename to clang-tools-extra/clang-tidy/readability/AmbiguousSmartptrResetCallCheck.h
index 474bcf1804581..05932e59e7928 100644
--- a/clang-tools-extra/clang-tidy/bugprone/SmartptrResetAmbiguousCallCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/AmbiguousSmartptrResetCallCheck.h
@@ -1,4 +1,4 @@
-//===--- SmartptrResetAmbiguousCallCheck.h - clang-tidy ---------*- C++ -*-===//
+//===--- AmbiguousSmartptrResetCallCheck.h - clang-tidy ---------*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,21 +6,21 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SMARTPTRRESETAMBIGUOUSCALLCHECK_H
-#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SMARTPTRRESETAMBIGUOUSCALLCHECK_H
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_AMBIGUOUSSMARTPTRRESETCALLCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_AMBIGUOUSSMARTPTRRESETCALLCHECK_H
 
 #include "../ClangTidyCheck.h"
 
-namespace clang::tidy::bugprone {
+namespace clang::tidy::readability {
 
 /// Finds potentially erroneous calls to 'reset' method on smart pointers when
 /// the pointee type also has a 'reset' method
 ///
 /// For the user-facing documentation see:
-/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone/smartptr-reset-ambiguous-call.html
-class SmartptrResetAmbiguousCallCheck : public ClangTidyCheck {
+/// http://clang.llvm.org/extra/clang-tidy/checks/readability/ambiguous-smartptr-reset-call.html
+class AmbiguousSmartptrResetCallCheck : public ClangTidyCheck {
 public:
-  SmartptrResetAmbiguousCallCheck(StringRef Name, ClangTidyContext *Context);
+  AmbiguousSmartptrResetCallCheck(StringRef Name, ClangTidyContext *Context);
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
@@ -32,6 +32,6 @@ class SmartptrResetAmbiguousCallCheck : public ClangTidyCheck {
   const std::vector<StringRef> SmartPointers;
 };
 
-} // namespace clang::tidy::bugprone
+} // namespace clang::tidy::readability
 
-#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SMARTPTRRESETAMBIGUOUSCALLCHECK_H
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_AMBIGUOUSSMARTPTRRESETCALLCHECK_H
diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
index 8f303c51e1b0d..4be1a8f831339 100644
--- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
   )
 
 add_clang_library(clangTidyReadabilityModule STATIC
+  AmbiguousSmartptrResetCallCheck.cpp
   AvoidConstParamsInDecls.cpp
   AvoidNestedConditionalOperatorCheck.cpp
   AvoidReturnWithVoidValueCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
index d61c0ba39658e..4c0812f0e6793 100644
--- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -9,6 +9,7 @@
 #include "../ClangTidy.h"
 #include "../ClangTidyModule.h"
 #include "../ClangTidyModuleRegistry.h"
+#include "AmbiguousSmartptrResetCallCheck.h"
 #include "AvoidConstParamsInDecls.h"
 #include "AvoidNestedConditionalOperatorCheck.h"
 #include "AvoidReturnWithVoidValueCheck.h"
@@ -68,6 +69,8 @@ namespace readability {
 class ReadabilityModule : public ClangTidyModule {
 public:
   void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
+    CheckFactories.registerCheck<AmbiguousSmartptrResetCallCheck>(
+        "readability-ambiguous-smartptr-reset-call");
     CheckFactories.registerCheck<AvoidConstParamsInDecls>(
         "readability-avoid-const-params-in-decls");
     CheckFactories.registerCheck<AvoidNestedConditionalOperatorCheck>(
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index ef48acf958c9e..ab3b1a1133038 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -91,8 +91,8 @@ Improvements to clang-tidy
 New checks
 ^^^^^^^^^^
 
-- New :doc:`bugprone-smartptr-reset-ambiguous-call
-  <clang-tidy/checks/bugprone/smartptr-reset-ambiguous-call>` check.
+- New :doc:`readability-ambiguous-smartptr-reset-call
+  <clang-tidy/checks/readability/ambiguous-smartptr-reset-call>` check.
 
   Finds potentially erroneous calls to ``reset`` method on smart pointers when
   the pointee type also has a ``reset`` method.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index ec6dd26b78977..f205ca64523bf 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -132,7 +132,6 @@ Clang-Tidy Checks
    :doc:`bugprone-signed-char-misuse <bugprone/signed-char-misuse>`,
    :doc:`bugprone-sizeof-container <bugprone/sizeof-container>`,
    :doc:`bugprone-sizeof-expression <bugprone/sizeof-expression>`,
-   :doc:`bugprone-smartptr-reset-ambiguous-call <bugprone/smartptr-reset-ambiguous-call>`, "Yes"
    :doc:`bugprone-spuriously-wake-up-functions <bugprone/spuriously-wake-up-functions>`,
    :doc:`bugprone-standalone-empty <bugprone/standalone-empty>`, "Yes"
    :doc:`bugprone-string-constructor <bugprone/string-constructor>`, "Yes"
@@ -353,6 +352,7 @@ Clang-Tidy Checks
    :doc:`portability-simd-intrinsics <portability/simd-intrinsics>`,
    :doc:`portability-std-allocator-const <portability/std-allocator-const>`,
    :doc:`portability-template-virtual-member-function <portability/template-virtual-member-function>`,
+   :doc:`readability-ambiguous-smartptr-reset-call <readability/ambiguous-smartptr-reset-call>`, "Yes"
    :doc:`readability-avoid-const-params-in-decls <readability/avoid-const-params-in-decls>`, "Yes"
    :doc:`readability-avoid-nested-conditional-operator <readability/avoid-nested-conditional-operator>`,
    :doc:`readability-avoid-return-with-void-value <readability/avoid-return-with-void-value>`, "Yes"
diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/smartptr-reset-ambiguous-call.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/ambiguous-smartptr-reset-call.rst
similarity index 70%
rename from clang-tools-extra/docs/clang-tidy/checks/bugprone/smartptr-reset-ambiguous-call.rst
rename to clang-tools-extra/docs/clang-tidy/checks/readability/ambiguous-smartptr-reset-call.rst
index 263105e420813..a34f6767339bf 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/smartptr-reset-ambiguous-call.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/ambiguous-smartptr-reset-call.rst
@@ -1,7 +1,7 @@
-.. title:: clang-tidy - bugprone-smartptr-reset-ambiguous-call
+.. title:: clang-tidy - readability-ambiguous-smartptr-reset-call
 
-bugprone-smartptr-reset-ambiguous-call
-======================================
+readability-ambiguous-smartptr-reset-call
+=========================================
 
 Finds potentially erroneous calls to ``reset`` method on smart pointers when
 the pointee type also has a ``reset`` method. Having a ``reset`` method in
@@ -35,13 +35,14 @@ access or direct assignment:
   ptr = nullptr;   // Clearly makes the pointer null
 
 The default smart pointers that are considered are ``std::unique_ptr``,
-``std::shared_ptr``. To specify other smart pointers or other classes use the
-:option:`SmartPointers` option.
+``std::shared_ptr``, ``boost::unique_ptr``, ``boost::shared_ptr``. To specify
+other smart pointers or other classes use the :option:`SmartPointers` option.
 
 Options
 -------
 
 .. option:: SmartPointers
 
-    Semicolon-separated list of class names of custom smart pointers.
-    Default value is `::std::unique_ptr;::std::shared_ptr`.
+    Semicolon-separated list of fully qualified class names of custom smart
+    pointers. Default value is `::std::unique_ptr;::std::shared_ptr;
+    ::boost::unique_ptr;::boost::shared_ptr`.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call-custom-pointers.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call-custom-pointers.cpp
deleted file mode 100644
index 2b8944c39619d..0000000000000
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call-custom-pointers.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-// RUN: %check_clang_tidy %s bugprone-smartptr-reset-ambiguous-call %t \
-// RUN: -config='{CheckOptions: \
-// RUN:  {bugprone-smartptr-reset-ambiguous-call.SmartPointers: "::std::unique_ptr;boost::shared_ptr"}}' \
-// RUN: --fix-notes --
-
-namespace std {
-
-template <typename T>
-struct unique_ptr {
-  T& operator*() const;
-  T* operator->() const;
-  void reset(T* p = nullptr);
-};
-
-template <typename T>
-struct shared_ptr {
-  T& operator*() const;
-  T* operator->() const;
-  void reset();
-  void reset(T*);
-};
-
-} // namespace std
-
-namespace boost {
-
-template <typename T>
-struct shared_ptr {
-  T& operator*() const;
-  T* operator->() const;
-  void reset();
-};
-
-} // namespace boost
-
-struct Resettable {
-  void reset();
-  void doSomething();
-};
-
-void Positive() {
-  std::unique_ptr<Resettable> u;
-  u.reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
-  // CHECK-FIXES: u = nullptr;
-  u->reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
-  // CHECK-FIXES: (*u).reset();
-
-  boost::shared_ptr<Resettable> s;
-  s.reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
-  // CHECK-FIXES: s = nullptr;
-  s->reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
-  // CHECK-FIXES: (*s).reset();
-}
-
-void Negative() {
-  std::shared_ptr<Resettable> s_ptr;
-  s_ptr.reset();
-  s_ptr->reset();
-  s_ptr->doSomething();
-
-  std::unique_ptr<Resettable> u_ptr;
-  u_ptr.reset(nullptr);
-  u_ptr->doSomething();
-}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call.cpp
deleted file mode 100644
index 4227733404f6b..0000000000000
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/smartptr-reset-ambiguous-call.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-// RUN: %check_clang_tidy %s bugprone-smartptr-reset-ambiguous-call %t --fix-notes --
-
-namespace std {
-
-template <typename T>
-struct unique_ptr {
-  T& operator*() const;
-  T* operator->() const;
-  void reset(T* p = nullptr);
-};
-
-template <typename T>
-struct shared_ptr {
-  T& operator*() const;
-  T* operator->() const;
-  void reset();
-  void reset(T*);
-};
-
-} // namespace std
-
-struct Resettable {
-  void reset();
-  void doSomething();
-};
-
-struct ResettableWithParam {
-  void reset(int a);
-  void doSomething();
-};
-
-struct ResettableWithDefaultParams {
-  void reset(int a = 0, double b = 0.0);
-  void doSomething();
-};
-
-struct NonResettable {
-  void doSomething();
-};
-
-void Positive() {
-  std::unique_ptr<Resettable> u;
-  u.reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
-  // CHECK-FIXES: u = nullptr;
-  u->reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
-  // CHECK-FIXES: (*u).reset();
-
-  std::shared_ptr<Resettable> s;
-  s.reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
-  // CHECK-FIXES: s = nullptr;
-  s->reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
-  // CHECK-FIXES: (*s).reset();
-
-  std::unique_ptr<std::unique_ptr<int>> uu_ptr;
-  uu_ptr.reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
-  // CHECK-FIXES: uu_ptr = nullptr;
-  uu_ptr->reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
-  // CHECK-FIXES: (*uu_ptr).reset();
-
-  std::unique_ptr<std::shared_ptr<int>> su_ptr;
-  su_ptr.reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
-  // CHECK-FIXES: su_ptr = nullptr;
-  su_ptr->reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
-  // CHECK-FIXES: (*su_ptr).reset();
-
-  std::unique_ptr<ResettableWithDefaultParams> rd;
-  rd.reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
-  // CHECK-FIXES: rd = nullptr;
-  rd->reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
-  // CHECK-FIXES: (*rd).reset();
-
-  std::unique_ptr<std::shared_ptr<std::unique_ptr<Resettable>>> nested_ptr;
-  nested_ptr.reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
-  // CHECK-FIXES: nested_ptr = nullptr;
-  nested_ptr->reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
-  // CHECK-FIXES: (*nested_ptr).reset();
-  (*nested_ptr).reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
-  // CHECK-FIXES: (*nested_ptr) = nullptr;
-  (*nested_ptr)->reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
-  // CHECK-FIXES: (*(*nested_ptr)).reset();
-  (**nested_ptr).reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
-  // CHECK-FIXES: (**nested_ptr) = nullptr;
-  (**nested_ptr)->reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
-  // CHECK-FIXES: (*(**nested_ptr)).reset();
-}
-
-void Negative() {
-  std::unique_ptr<Resettable> u_ptr;
-  u_ptr.reset(nullptr);
-  u_ptr->doSomething();
-
-  std::shared_ptr<Resettable> s_ptr;
-  s_ptr.reset(nullptr);
-  s_ptr->doSomething();
-  
-  Resettable* raw_ptr;
-  raw_ptr->reset();
-  raw_ptr->doSomething();
-
-  Resettable resettable;
-  resettable.reset();
-  resettable.doSomething();
-  
-  std::unique_ptr<ResettableWithParam> u_ptr_param;
-  u_ptr_param.reset();
-  u_ptr_param.reset(nullptr);
-  u_ptr_param->reset(0);
-
-  std::unique_ptr<NonResettable> u_ptr_no_reset;
-  u_ptr_no_reset.reset();
-
-  std::shared_ptr<ResettableWithParam> s_ptr_param;
-  s_ptr_param.reset();
-  s_ptr_param->reset(0);
-  s_ptr_param->doSomething();
-
-  std::shared_ptr<NonResettable> s_ptr_no_reset;
-  s_ptr_no_reset.reset();
-
-  std::unique_ptr<ResettableWithDefaultParams> u_ptr_default_params;
-  u_ptr_default_params.reset(nullptr);
-  u_ptr_default_params->reset(1);
-  u_ptr_default_params->reset(1, 2.0);
-}
-
-template <typename T>
-void TemplatePositiveTest() {
-  std::unique_ptr<T> u_ptr;
-
-  u_ptr.reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
-  // CHECK-FIXES: u_ptr = nullptr;
-  u_ptr->reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
-  // CHECK-FIXES: (*u_ptr).reset();
-
-  std::shared_ptr<T> s_ptr;
-  s_ptr.reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: assign the pointer to 'nullptr'
-  // CHECK-FIXES: s_ptr = nullptr;
-  s_ptr->reset();
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
-  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: use dereference to call 'reset' method of the pointee
-  // CHECK-FIXES: (*s_ptr).reset();
-}
-
-template <typename T>
-void TemplatNegativeTestTypeWithReset() {
-  std::unique_ptr<T> u_ptr;
-  u_ptr.reset();
-  u_ptr->reset(0);
-
-  std::shared_ptr<T> s_ptr;
-  s_ptr.reset();
-  s_ptr->reset(0);
-}
-
-template <typename T>
-void TemplatNegativeTestTypeWithoutReset() {
-  std::unique_ptr<T> u_ptr;
-  u_ptr.reset();
-
-  std::unique_ptr<T> s_ptr;
-  s_ptr.reset();
-}
-
-void instantiate() {
-  TemplatePositiveTest<Resettable>();
-  TemplatePositiveTest<std::unique_ptr<int>>();
-  TemplatePositiveTest<std::shared_ptr<int>>();
-  TemplatNegativeTestTypeWithReset<ResettableWithParam>();
-  TemplatNegativeTestTypeWithoutReset<NonResettable>();
-}
-
-struct S {
-  void foo() {
-    u_ptr.reset();
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
-    // CHECK-MESSAGES: :[[@LINE-2]]:5: note: assign the pointer to 'nullptr'
-    // CHECK-FIXES: u_ptr = nullptr;
-    u_ptr->reset();
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
-    // CHECK-MESSAGES: :[[@LINE-2]]:5: note: use dereference to call 'reset' method of the pointee
-    // CHECK-FIXES: (*u_ptr).reset();
-    u_ptr.reset(nullptr);
-    u_ptr->doSomething();
-
-    s_ptr.reset();
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: be explicit when calling 'reset()' on a smart pointer with a pointee that has a 'reset()' method
-    // CHECK-MESSAGES: :[[@LINE-2]]:5: note: assign the pointer to 'nullptr'
-    // CHECK-FIXES: s_ptr = nullptr;
-    s_ptr->reset();
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: be explicit when calling 'reset()' on a pointee of a smart pointer
-    // CHECK-MESSAGES: :[[@LINE-2]]:5: note: use dereference to call 'reset' method of the pointee
-    // CHECK-FIXES: (*s_ptr).reset();
-    s_ptr.reset(nullptr);
-
-    ptr.reset();
-  }
-
-  std::unique_ptr<Resettable> u_ptr;
-  std::unique_ptr<std::shared_ptr<int>> s_ptr;
-  std::unique_ptr<NonResettable> ptr;
-};
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/ambiguous-smartptr-reset-call-custom-pointers.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/ambiguous-smartptr-reset-call-custom-pointers.cpp
new file mode 100644
index 0000000000000..7dc6745ada16b
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/ambiguous-smartptr-reset-call-custom-pointers.cpp
@@ -0,0 +1,68 @@
+// RUN: %check_clang_tidy %s readability-ambiguous-smartptr-reset-call %t \
+// RUN: -config='{CheckOptions: \
+// RUN:  {readability-ambiguous-smartptr-reset-call.SmartPointers: "::std::unique_ptr;::other_ptr"}}' \
+// RUN: --fix-notes --
+
+namespace std {
+
+template <typename T>
+struct unique_ptr {
+  T& operator*() const;
+  T* operator->() const;
+  void reset(T* p = nullptr);
+};
+
+template <typename T>
+struct shared_ptr {
+  T& operator*() const;
+  T* operator->() const;
+  void reset();
+  void reset(T*);
+};
+
+} // namespace std
+
+template <typename T>
+struct other_ptr {
+  T& operator*() const;
+  T* operator->() const;
+  void reset();
+};
+
+struct Resettable {
+  void reset();
+  void doSomething();
+};
+
+void Positive() {
+  std::unique_ptr<Resettable> u;
+  u.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: u = nullptr;
+  u->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*u).reset();
+
+  other_ptr<Resettable> s;
+  s.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: s = nullptr;
+  s->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*s).reset();
+}
+
+void Negative() {
+  std::shared_ptr<Resettable> s_ptr;
+  s_ptr.reset();
+  s_ptr->reset();
+  s_ptr->doSomething();
+
+  std::unique_ptr<Resettable> u_ptr;
+  u_ptr.reset(nullptr);
+  u_ptr->doSomething();
+}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/ambiguous-smartptr-reset-call.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/ambiguous-smartptr-reset-call.cpp
new file mode 100644
index 0000000000000..8b74e287af46e
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/ambiguous-smartptr-reset-call.cpp
@@ -0,0 +1,239 @@
+// RUN: %check_clang_tidy %s readability-ambiguous-smartptr-reset-call %t --fix-notes --
+
+namespace std {
+
+template <typename T>
+struct unique_ptr {
+  T& operator*() const;
+  T* operator->() const;
+  void reset(T* p = nullptr);
+};
+
+template <typename T>
+struct shared_ptr {
+  T& operator*() const;
+  T* operator->() const;
+  void reset();
+  void reset(T*);
+};
+
+} // namespace std
+
+struct Resettable {
+  void reset();
+  void doSomething();
+};
+
+struct ResettableWithParam {
+  void reset(int a);
+  void doSomething();
+};
+
+struct ResettableWithDefaultParams {
+  void reset(int a = 0, double b = 0.0);
+  void doSomething();
+};
+
+struct NonResettable {
+  void doSomething();
+};
+
+void Positive() {
+  std::unique_ptr<Resettable> u;
+  u.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: u = nullptr;
+  u->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*u).reset();
+
+  std::shared_ptr<Resettable> s;
+  s.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: s = nullptr;
+  s->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*s).reset();
+
+  std::unique_ptr<std::unique_ptr<int>> uu_ptr;
+  uu_ptr.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: uu_ptr = nullptr;
+  uu_ptr->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*uu_ptr).reset();
+
+  std::unique_ptr<std::shared_ptr<int>> su_ptr;
+  su_ptr.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: su_ptr = nullptr;
+  su_ptr->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*su_ptr).reset();
+
+  std::unique_ptr<ResettableWithDefaultParams> rd;
+  rd.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: rd = nullptr;
+  rd->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*rd).reset();
+
+  std::unique_ptr<std::shared_ptr<std::unique_ptr<Resettable>>> nested_ptr;
+  nested_ptr.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: nested_ptr = nullptr;
+  nested_ptr->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*nested_ptr).reset();
+  (*nested_ptr).reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: (*nested_ptr) = nullptr;
+  (*nested_ptr)->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*(*nested_ptr)).reset();
+  (**nested_ptr).reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: (**nested_ptr) = nullptr;
+  (**nested_ptr)->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*(**nested_ptr)).reset();
+}
+
+void Negative() {
+  std::unique_ptr<Resettable> u_ptr;
+  u_ptr.reset(nullptr);
+  u_ptr->doSomething();
+
+  std::shared_ptr<Resettable> s_ptr;
+  s_ptr.reset(nullptr);
+  s_ptr->doSomething();
+  
+  Resettable* raw_ptr;
+  raw_ptr->reset();
+  raw_ptr->doSomething();
+
+  Resettable resettable;
+  resettable.reset();
+  resettable.doSomething();
+  
+  std::unique_ptr<ResettableWithParam> u_ptr_param;
+  u_ptr_param.reset();
+  u_ptr_param.reset(nullptr);
+  u_ptr_param->reset(0);
+
+  std::unique_ptr<NonResettable> u_ptr_no_reset;
+  u_ptr_no_reset.reset();
+
+  std::shared_ptr<ResettableWithParam> s_ptr_param;
+  s_ptr_param.reset();
+  s_ptr_param->reset(0);
+  s_ptr_param->doSomething();
+
+  std::shared_ptr<NonResettable> s_ptr_no_reset;
+  s_ptr_no_reset.reset();
+
+  std::unique_ptr<ResettableWithDefaultParams> u_ptr_default_params;
+  u_ptr_default_params.reset(nullptr);
+  u_ptr_default_params->reset(1);
+  u_ptr_default_params->reset(1, 2.0);
+}
+
+template <typename T>
+void TemplatePositiveTest() {
+  std::unique_ptr<T> u_ptr;
+
+  u_ptr.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: u_ptr = nullptr;
+  u_ptr->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*u_ptr).reset();
+
+  std::shared_ptr<T> s_ptr;
+  s_ptr.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: s_ptr = nullptr;
+  s_ptr->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*s_ptr).reset();
+}
+
+template <typename T>
+void TemplatNegativeTestTypeWithReset() {
+  std::unique_ptr<T> u_ptr;
+  u_ptr.reset();
+  u_ptr->reset(0);
+
+  std::shared_ptr<T> s_ptr;
+  s_ptr.reset();
+  s_ptr->reset(0);
+}
+
+template <typename T>
+void TemplatNegativeTestTypeWithoutReset() {
+  std::unique_ptr<T> u_ptr;
+  u_ptr.reset();
+
+  std::unique_ptr<T> s_ptr;
+  s_ptr.reset();
+}
+
+void instantiate() {
+  TemplatePositiveTest<Resettable>();
+  TemplatePositiveTest<std::unique_ptr<int>>();
+  TemplatePositiveTest<std::shared_ptr<int>>();
+  TemplatNegativeTestTypeWithReset<ResettableWithParam>();
+  TemplatNegativeTestTypeWithoutReset<NonResettable>();
+}
+
+struct S {
+  void foo() {
+    u_ptr.reset();
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+    // CHECK-MESSAGES: :[[@LINE-2]]:5: note: consider assigning the pointer to 'nullptr' here
+    // CHECK-FIXES: u_ptr = nullptr;
+    u_ptr->reset();
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+    // CHECK-MESSAGES: :[[@LINE-2]]:5: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+    // CHECK-FIXES: (*u_ptr).reset();
+    u_ptr.reset(nullptr);
+    u_ptr->doSomething();
+
+    s_ptr.reset();
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+    // CHECK-MESSAGES: :[[@LINE-2]]:5: note: consider assigning the pointer to 'nullptr' here
+    // CHECK-FIXES: s_ptr = nullptr;
+    s_ptr->reset();
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+    // CHECK-MESSAGES: :[[@LINE-2]]:5: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+    // CHECK-FIXES: (*s_ptr).reset();
+    s_ptr.reset(nullptr);
+
+    ptr.reset();
+  }
+
+  std::unique_ptr<Resettable> u_ptr;
+  std::unique_ptr<std::shared_ptr<int>> s_ptr;
+  std::unique_ptr<NonResettable> ptr;
+};

>From 2ad06940391f3d0d8bbacc94f305f763fdf6ec93 Mon Sep 17 00:00:00 2001
From: Victor Baranov <bar.victor.2002 at gmail.com>
Date: Mon, 17 Feb 2025 23:23:16 +0300
Subject: [PATCH 4/4] [clang-tidy] add typedef and using processing, enchances
 docs with std:optional

---
 .../AmbiguousSmartptrResetCallCheck.cpp       |  26 +--
 .../ambiguous-smartptr-reset-call.rst         |   9 +-
 .../ambiguous-smartptr-reset-call.cpp         | 174 ++++++++++++++++++
 3 files changed, 192 insertions(+), 17 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/readability/AmbiguousSmartptrResetCallCheck.cpp b/clang-tools-extra/clang-tidy/readability/AmbiguousSmartptrResetCallCheck.cpp
index 86dc9a33c0755..b84fefd2c2814 100644
--- a/clang-tools-extra/clang-tidy/readability/AmbiguousSmartptrResetCallCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/AmbiguousSmartptrResetCallCheck.cpp
@@ -38,7 +38,9 @@ AST_MATCHER(CXXMethodDecl, hasOnlyDefaultParameters) {
   return true;
 }
 
-const auto DefaultSmartPointers = "::std::shared_ptr;::std::unique_ptr";
+const auto DefaultSmartPointers =
+    "::std::shared_ptr;::std::unique_ptr;::std::optional;"
+    "::boost::shared_ptr;::boost::scoped_ptr";
 } // namespace
 
 AmbiguousSmartptrResetCallCheck::AmbiguousSmartptrResetCallCheck(
@@ -64,17 +66,18 @@ void AmbiguousSmartptrResetCallCheck::registerMatchers(MatchFinder *Finder) {
             classTemplateSpecializationDecl(
                 hasSpecializedTemplate(classTemplateDecl(has(ResetMethod)))));
 
-  const auto SmartptrWithBugproneReset = classTemplateSpecializationDecl(
-      IsSmartptr,
-      hasTemplateArgument(
-          0, templateArgument(refersToType(hasUnqualifiedDesugaredType(
-                 recordType(hasDeclaration(TypeWithReset)))))));
+  const auto SmartptrWithReset = hasType(hasUnqualifiedDesugaredType(
+      recordType(hasDeclaration(classTemplateSpecializationDecl(
+          IsSmartptr,
+          hasTemplateArgument(
+              0, templateArgument(refersToType(hasUnqualifiedDesugaredType(
+                     recordType(hasDeclaration(TypeWithReset)))))))))));
 
   // Find a.reset() calls
   Finder->addMatcher(
-      cxxMemberCallExpr(callee(memberExpr(member(hasName("reset")))),
+      cxxMemberCallExpr(callee(memberExpr(member(ResetMethod))),
                         everyArgumentMatches(cxxDefaultArgExpr()),
-                        on(expr(hasType(SmartptrWithBugproneReset))))
+                        on(expr(SmartptrWithReset)))
           .bind("smartptrResetCall"),
       this);
 
@@ -84,11 +87,8 @@ void AmbiguousSmartptrResetCallCheck::registerMatchers(MatchFinder *Finder) {
           callee(memberExpr(
               member(ResetMethod),
               hasObjectExpression(
-                  cxxOperatorCallExpr(
-                      hasOverloadedOperatorName("->"),
-                      hasArgument(
-                          0, expr(hasType(
-                                 classTemplateSpecializationDecl(IsSmartptr)))))
+                  cxxOperatorCallExpr(hasOverloadedOperatorName("->"),
+                                      hasArgument(0, expr(SmartptrWithReset)))
                       .bind("OpCall")))),
           everyArgumentMatches(cxxDefaultArgExpr()))
           .bind("objectResetCall"),
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/ambiguous-smartptr-reset-call.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/ambiguous-smartptr-reset-call.rst
index a34f6767339bf..e76aeb93796ab 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/ambiguous-smartptr-reset-call.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/ambiguous-smartptr-reset-call.rst
@@ -34,9 +34,10 @@ access or direct assignment:
   (*ptr).reset();  // Clearly calls underlying reset method
   ptr = nullptr;   // Clearly makes the pointer null
 
-The default smart pointers that are considered are ``std::unique_ptr``,
-``std::shared_ptr``, ``boost::unique_ptr``, ``boost::shared_ptr``. To specify
-other smart pointers or other classes use the :option:`SmartPointers` option.
+The default smart pointers and classes that are considered are
+``std::unique_ptr``, ``std::shared_ptr``, ``std::optional``,
+``boost::shared_ptr``, ``boost::scoped_ptr``. To specify other smart pointers
+or other classes use the :option:`SmartPointers` option.
 
 Options
 -------
@@ -45,4 +46,4 @@ Options
 
     Semicolon-separated list of fully qualified class names of custom smart
     pointers. Default value is `::std::unique_ptr;::std::shared_ptr;
-    ::boost::unique_ptr;::boost::shared_ptr`.
+    ::std::optional;::boost::unique_ptr;::boost::shared_ptr`.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/ambiguous-smartptr-reset-call.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/ambiguous-smartptr-reset-call.cpp
index 8b74e287af46e..1175bfd95ad11 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/ambiguous-smartptr-reset-call.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/ambiguous-smartptr-reset-call.cpp
@@ -237,3 +237,177 @@ struct S {
   std::unique_ptr<std::shared_ptr<int>> s_ptr;
   std::unique_ptr<NonResettable> ptr;
 };
+
+
+typedef std::unique_ptr<Resettable> TypedefResettableUniquePtr;
+typedef std::shared_ptr<Resettable> TypedefResettableSharedPtr;
+
+void TypedefPositive() {
+  TypedefResettableUniquePtr u_ptr;
+  u_ptr.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: u_ptr = nullptr;
+  u_ptr->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*u_ptr).reset();
+
+  TypedefResettableSharedPtr s_ptr;
+  s_ptr.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: s_ptr = nullptr;
+
+  s_ptr->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*s_ptr).reset();
+}
+
+using UsingResettableUniquePtr = std::unique_ptr<Resettable>;
+using UsingResettableSharedPtr = std::shared_ptr<Resettable>;
+
+void UsingPositive() {
+  UsingResettableUniquePtr u_ptr;
+  u_ptr.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: u_ptr = nullptr;
+  u_ptr->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*u_ptr).reset();
+
+  UsingResettableSharedPtr s_ptr;
+  s_ptr.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: s_ptr = nullptr;
+
+  s_ptr->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*s_ptr).reset();
+}
+
+template<typename T>
+using UsingUniquePtr = std::unique_ptr<T>;
+template<typename T>
+using UsingSharedPtr = std::shared_ptr<T>;
+
+void UsingTemplatePositive() {
+  UsingUniquePtr<Resettable> u_ptr;
+  u_ptr.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: u_ptr = nullptr;
+  u_ptr->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*u_ptr).reset();
+
+  UsingSharedPtr<Resettable> s_ptr;
+  s_ptr.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: s_ptr = nullptr;
+
+  s_ptr->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*s_ptr).reset();
+}
+
+template<typename T>
+void UsingByTemplatePositive() {
+  UsingUniquePtr<T> u_ptr;
+  u_ptr.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: u_ptr = nullptr;
+  u_ptr->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*u_ptr).reset();
+
+  UsingSharedPtr<T> s_ptr;
+  s_ptr.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: s_ptr = nullptr;
+
+  s_ptr->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*s_ptr).reset();
+}
+
+void instantiate2() {
+  UsingByTemplatePositive<Resettable>();
+}
+
+
+// Check other default pointers and classes.
+namespace std {
+
+template <typename T>
+struct optional {
+  T& operator*() const;
+  T* operator->() const;
+  void reset();
+};
+
+} // namespace std
+
+namespace boost {
+
+template <typename T>
+struct scoped_ptr {
+  T& operator*() const;
+  T* operator->() const;
+  void reset(T* p = 0);
+};
+
+template <typename T>
+struct shared_ptr {
+  T& operator*() const;
+  T* operator->() const;
+  void reset();
+  void reset(T*);
+};
+
+} // namespace boost
+
+void PositiveOtherClasses() {
+  boost::scoped_ptr<Resettable> sc;
+  sc.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: sc = nullptr;
+  sc->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*sc).reset();
+
+  boost::shared_ptr<Resettable> sh;
+  sh.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: sh = nullptr;
+  sh->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*sh).reset();
+
+  std::optional<Resettable> o;
+  o.reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a smart pointer with pointee that also has a 'reset()' method, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider assigning the pointer to 'nullptr' here
+  // CHECK-FIXES: o = nullptr;
+  o->reset();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: ambiguous call to 'reset()' on a pointee of a smart pointer, prefer more explicit approach
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: note: consider dereferencing smart pointer to call 'reset' method of the pointee here
+  // CHECK-FIXES: (*o).reset();
+}
+



More information about the cfe-commits mailing list