[clang-tools-extra] [clang-tidy] Enhance modernize-use-starts-ends-with to handle substr patterns (PR #116033)

Nicolas van Kempen via cfe-commits cfe-commits at lists.llvm.org
Sun Nov 17 18:16:37 PST 2024


================
@@ -171,10 +182,64 @@ void UseStartsEndsWithCheck::registerMatchers(MatchFinder *Finder) {
                              hasRHS(lengthExprForStringNode("needle")))))
           .bind("expr"),
       this);
+
+  Finder->addMatcher(
+      cxxOperatorCallExpr(
+          hasAnyOperatorName("==", "!="),
+          anyOf(
+              hasOperands(
+                  cxxMemberCallExpr(
+                      argumentCountIs(2), hasArgument(0, ZeroLiteral),
+                      hasArgument(1, lengthExprForStringNode("needle")),
+                      callee(
+                          cxxMethodDecl(hasName("substr"),
+                                        ofClass(OnClassWithStartsWithFunction))
+                              .bind("find_fun")))
+                      .bind("find_expr"),
+                  expr().bind("needle")),
+              hasOperands(expr().bind("needle"),
+                          cxxMemberCallExpr(
+                              argumentCountIs(2), hasArgument(0, ZeroLiteral),
+                              hasArgument(1, lengthExprForStringNode("needle")),
+                              callee(cxxMethodDecl(
+                                         hasName("substr"),
+                                         ofClass(OnClassWithStartsWithFunction))
+                                         .bind("find_fun")))
+                              .bind("find_expr"))))
+          .bind("expr"),
+      this);
----------------
nicovank wrote:

`hasOperands` already does this "one way or the other" commutative logic. In fact here, `expr().bind("needle")` needs to be first, because then we use the binding for the second operand (`lengthExprForStringNode("needle")`). The other option would never yield a match.

```suggestion
Finder->addMatcher(
    cxxOperatorCallExpr(
        hasAnyOperatorName("==", "!="),
        hasOperands(
            expr().bind("needle"),
            cxxMemberCallExpr(
                argumentCountIs(2), hasArgument(0, ZeroLiteral),
                hasArgument(1, lengthExprForStringNode("needle")),
                callee(cxxMethodDecl(hasName("substr"),
                                     ofClass(OnClassWithStartsWithFunction))
                           .bind("find_fun")))
                .bind("find_expr")))
        .bind("expr"),
    this);
```

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


More information about the cfe-commits mailing list