================
@@ -0,0 +1,134 @@
+//===--- 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 "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) {
+  if (Node.getNumArgs() == 0)
+    return true;
+
+  for (const auto *Arg : Node.arguments()) {
+    if (!InnerMatcher.matches(*Arg, Finder, Builder))
+      return false;
+  }
+  return true;
+}
+
+AST_MATCHER(CXXMethodDecl, hasOnlyDefaultArgs) {
+  if (Node.param_empty())
+    return true;
+
+  for (const auto *Param : Node.parameters()) {
+    if (!Param->hasDefaultArg())
+      return false;
+  }
+  return true;
+}
+
+} // namespace
+
+void SmartptrResetAmbiguousCallCheck::registerMatchers(MatchFinder *Finder) {
+  const auto IsSmartptr = hasAnyName("::std::unique_ptr", "::std::shared_ptr");
+
+  const auto ResetMethod =
+      cxxMethodDecl(hasName("reset"), hasOnlyDefaultArgs());
+
+  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) {
+  const auto *SmartptrResetCall =
+      Result.Nodes.getNodeAs<CXXMemberCallExpr>("smartptrResetCall");
+  const auto *ObjectResetCall =
+      Result.Nodes.getNodeAs<CXXMemberCallExpr>("objectResetCall");
----------------
5chmidti wrote:

Please move these into each of the `if` conditions to potentially save the one 
lookup from `objectResetCall`:

```c++
if (const auto *SmartptrResetCall = 
Result.Nodes.getNodeAs<CXXMemberCallExpr>("smartptrResetCall")) {
...
}
```

https://github.com/llvm/llvm-project/pull/121291
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to