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

Piotr Zegar via cfe-commits cfe-commits at lists.llvm.org
Sun Feb 23 09:30:30 PST 2025


================
@@ -0,0 +1,129 @@
+//===--- 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.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "AmbiguousSmartptrResetCallCheck.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::readability {
+
+namespace {
+
+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;"
+                                  "::boost::shared_ptr";
+} // namespace
+
+AmbiguousSmartptrResetCallCheck::AmbiguousSmartptrResetCallCheck(
+    StringRef Name, ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context),
+      SmartPointers(utils::options::parseStringList(
+          Options.get("SmartPointers", DefaultSmartPointers))) {}
+
+void AmbiguousSmartptrResetCallCheck::storeOptions(
+    ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "SmartPointers",
+                utils::options::serializeStringList(SmartPointers));
+}
+
+void AmbiguousSmartptrResetCallCheck::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 SmartptrWithReset = expr(hasType(hasUnqualifiedDesugaredType(
+      recordType(hasDeclaration(classTemplateSpecializationDecl(
+          IsSmartptr,
+          hasTemplateArgument(
+              0, templateArgument(refersToType(hasUnqualifiedDesugaredType(
+                     recordType(hasDeclaration(TypeWithReset))))))))))));
+
+  Finder->addMatcher(
+      cxxMemberCallExpr(
+          callee(ResetMethod),
+          unless(hasAnyArgument(expr(unless(cxxDefaultArgExpr())))),
+          anyOf(on(SmartptrWithReset),
+                on(cxxOperatorCallExpr(hasOverloadedOperatorName("->"),
+                                       hasArgument(0, SmartptrWithReset))
+                       .bind("ArrowOp"))))
+          .bind("MemberCall"),
+      this);
+}
+
+void AmbiguousSmartptrResetCallCheck::check(
+    const MatchFinder::MatchResult &Result) {
+
+  if (const auto *Arrow =
+          Result.Nodes.getNodeAs<CXXOperatorCallExpr>("ArrowOp")) {
+    const auto *ObjectResetCall =
+        Result.Nodes.getNodeAs<CXXMemberCallExpr>("MemberCall");
----------------
PiotrZSL wrote:

duplicated member call, just move it before if and use in both if's

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


More information about the cfe-commits mailing list