[PATCH] D76496: [clang-tidy] add support to 3-arg find() in StringFindStartswith

Niko Weh via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 27 10:04:12 PDT 2020


niko updated this revision to Diff 288378.
niko added a comment.

Rebasing to HEAD


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D76496/new/

https://reviews.llvm.org/D76496

Files:
  clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
  clang-tools-extra/test/clang-tidy/checkers/abseil-string-find-startswith.cpp


Index: clang-tools-extra/test/clang-tidy/checkers/abseil-string-find-startswith.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/abseil-string-find-startswith.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/abseil-string-find-startswith.cpp
@@ -13,6 +13,7 @@
   ~basic_string();
   int find(basic_string<C> s, int pos = 0);
   int find(const char *s, int pos = 0);
+  int find(const char *s, int pos, int n);
 };
 typedef basic_string<char> string;
 typedef basic_string<wchar_t> wstring;
@@ -41,6 +42,10 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith
   // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(s, s);{{$}}
 
+  s.find(s, 0) == 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith
+  // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(s, s);{{$}}
+
   s.find("aaa") != 0;
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use !absl::StartsWith
   // CHECK-FIXES: {{^[[:space:]]*}}!absl::StartsWith(s, "aaa");{{$}}
@@ -61,9 +66,14 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith
   // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(s2, "a");{{$}}
 
+  s.find("a", 0, 1) == 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use absl::StartsWith
+  // CHECK-FIXES: {{^[[:space:]]*}}absl::StartsWith(s, absl::string_view("a", 1));{{$}}
+
   // expressions that don't trigger the check are here.
   A_MACRO(s.find("a"), 0);
   s.find("a", 1) == 0;
   s.find("a", 1) == 1;
   s.find("a") == 1;
+  s.find("a", 1, 1) == 0;
 }
Index: clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
+++ clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
@@ -40,12 +40,13 @@
 
   auto StringFind = cxxMemberCallExpr(
       // .find()-call on a string...
-      callee(cxxMethodDecl(hasName("find"))),
-      on(hasType(StringType)),
+      callee(cxxMethodDecl(hasName("find"))), on(hasType(StringType)),
       // ... with some search expression ...
       hasArgument(0, expr().bind("needle")),
       // ... and either "0" as second argument or the default argument (also 0).
-      anyOf(hasArgument(1, ZeroLiteral), hasArgument(1, cxxDefaultArgExpr())));
+      anyOf(hasArgument(1, ZeroLiteral), hasArgument(1, cxxDefaultArgExpr())),
+      // ... and optionally a third argument for 'search string length'.
+      optionally(hasArgument(2, expr().bind("needle_length"))));
 
   Finder->addMatcher(
       // Match [=!]= with a zero on one side and a string.find on the other.
@@ -69,6 +70,7 @@
   const Expr *Haystack = Result.Nodes.getNodeAs<CXXMemberCallExpr>("findexpr")
                              ->getImplicitObjectArgument();
   assert(Haystack != nullptr);
+  const auto *NeedleLength = Result.Nodes.getNodeAs<Expr>("needle_length");
 
   if (ComparisonExpr->getBeginLoc().isMacroID())
     return;
@@ -82,6 +84,20 @@
       CharSourceRange::getTokenRange(Haystack->getSourceRange()), Source,
       Context.getLangOpts());
 
+  // If there is a third argument (search string length), create an
+  // absl::string_view(search string, search string length) and use that
+  // as the search string in StartsWith.
+  std::string NewNeedleStr;
+  if (NeedleLength != nullptr) {
+    const StringRef NeedleLengthCode = Lexer::getSourceText(
+        CharSourceRange::getTokenRange(NeedleLength->getSourceRange()), Source,
+        Context.getLangOpts());
+    NewNeedleStr = std::string("absl::string_view(") + NeedleExprCode.str() +
+                   ", " + NeedleLengthCode.str() + ")";
+  } else {
+    NewNeedleStr = NeedleExprCode.str();
+  }
+
   // Create the StartsWith string, negating if comparison was "!=".
   bool Neg = ComparisonExpr->getOpcodeStr() == "!=";
   StringRef StartswithStr;
@@ -100,7 +116,7 @@
 
   Diagnostic << FixItHint::CreateReplacement(
       ComparisonExpr->getSourceRange(),
-      (StartswithStr + "(" + HaystackExprCode + ", " + NeedleExprCode + ")")
+      (StartswithStr + "(" + HaystackExprCode + ", " + NewNeedleStr + ")")
           .str());
 
   // Create a preprocessor #include FixIt hint (CreateIncludeInsertion checks


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D76496.288378.patch
Type: text/x-patch
Size: 4269 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200827/f30d5ac2/attachment.bin>


More information about the cfe-commits mailing list