Skip to content

Commit e379faf

Browse files
committed
[clang-tidy] add more matched-cases
1 parent c3f21bb commit e379faf

File tree

4 files changed

+54
-14
lines changed

4 files changed

+54
-14
lines changed

clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -113,22 +113,33 @@ void UseStartsEndsWithCheck::registerMatchers(MatchFinder *Finder) {
113113
const auto OnClassWithEndsWithFunction = ClassTypeWithMethod(
114114
"ends_with_fun", "ends_with", "endsWith", "endswith", "EndsWith");
115115

116-
// Case 1: X.find(Y, [0]) [!=]= 0 -> starts_with.
116+
// Case 1: X.find(Y, [0], [LEN(Y)]) [!=]= 0 -> starts_with.
117117
const auto FindExpr = cxxMemberCallExpr(
118-
anyOf(argumentCountIs(1),
119-
allOf(argumentCountIs(2), hasArgument(1, ZeroLiteral))),
120118
callee(
121119
cxxMethodDecl(hasName("find"), ofClass(OnClassWithStartsWithFunction))
122120
.bind("find_fun")),
123-
hasArgument(0, expr().bind("needle")));
124-
125-
// Case 2: X.rfind(Y, 0) [!=]= 0 -> starts_with.
121+
hasArgument(0, expr().bind("needle")),
122+
anyOf(
123+
// Detect the expression: X.find(Y);
124+
argumentCountIs(1),
125+
// Detect the expression: X.find(Y, 0);
126+
allOf(argumentCountIs(2), hasArgument(1, ZeroLiteral)),
127+
// Detect the expression: X.find(Y, 0, LEN(Y));
128+
allOf(argumentCountIs(3), hasArgument(1, ZeroLiteral),
129+
hasArgument(2, lengthExprForStringNode("needle")))));
130+
131+
// Case 2: X.rfind(Y, 0, [LEN(Y)]) [!=]= 0 -> starts_with.
126132
const auto RFindExpr = cxxMemberCallExpr(
127-
argumentCountIs(2), hasArgument(1, ZeroLiteral),
128133
callee(cxxMethodDecl(hasName("rfind"),
129134
ofClass(OnClassWithStartsWithFunction))
130135
.bind("find_fun")),
131-
hasArgument(0, expr().bind("needle")));
136+
hasArgument(0, expr().bind("needle")),
137+
anyOf(
138+
// Detect the expression: X.rfind(Y, 0);
139+
allOf(argumentCountIs(2), hasArgument(1, ZeroLiteral)),
140+
// Detect the expression: X.rfind(Y, 0, LEN(Y));
141+
allOf(argumentCountIs(3), hasArgument(1, ZeroLiteral),
142+
hasArgument(2, lengthExprForStringNode("needle")))));
132143

133144
// Case 3: X.compare(0, LEN(Y), Y) [!=]= 0 -> starts_with.
134145
const auto CompareExpr = cxxMemberCallExpr(

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ Changes in existing checks
128128
<clang-tidy/checks/misc/redundant-expression>` check by providing additional
129129
examples and fixing some macro related false positives.
130130

131+
- Improved :doc:`modernize-use-starts-ends-with
132+
<clang-tidy/checks/modernize/use-starts-ends-with>` check by fixing false
133+
positives on methods ``find`` and ``rfind`` called with three arguments.
134+
131135
- Improved :doc:`performance/unnecessary-value-param
132136
<clang-tidy/checks/performance/unnecessary-value-param>` check performance by
133137
tolerating fix-it breaking compilation when functions is used as pointers
@@ -137,10 +141,6 @@ Changes in existing checks
137141
<clang-tidy/checks/performance/move-const-arg>` check by fixing false negatives
138142
on ternary operators calling ``std::move``.
139143

140-
- Improved :doc:`modernize-use-starts-ends-with
141-
<clang-tidy/checks/modernize/use-starts-ends-with>` check by fixing false
142-
positives on methods ``find`` and ``rfind`` called with three arguments.
143-
144144
Removed checks
145145
^^^^^^^^^^^^^^
146146

clang-tools-extra/docs/clang-tidy/checks/modernize/use-starts-ends-with.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ Expression Replacement
1414
---------------------------------------------------- ---------------------
1515
``u.find(v) == 0`` ``u.starts_with(v)``
1616
``u.find(v, 0) == 0`` ``u.starts_with(v)``
17+
``u.find(v, 0, v.size()) == 0`` ``u.starts_with(v)``
1718
``u.rfind(v, 0) != 0`` ``!u.starts_with(v)``
19+
``u.rfind(v, 0, v.size()) != 0`` ``!u.starts_with(v)``
1820
``u.compare(0, v.size(), v) == 0`` ``u.starts_with(v)``
1921
``u.substr(0, v.size()) == v`` ``u.starts_with(v)``
2022
``v != u.substr(0, v.size())`` ``!u.starts_with(v)``

clang-tools-extra/test/clang-tidy/checkers/modernize/use-starts-ends-with.cpp

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,30 @@ void test(std::string s, std::string_view sv, sub_string ss, sub_sub_string sss,
248248
// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
249249
// CHECK-FIXES: s.starts_with(s);
250250

251+
s.find("aaa", 0, 3) == 0;
252+
// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
253+
// CHECK-FIXES: s.starts_with("aaa");
254+
255+
s.find("aaa", ZERO, 3) == 0;
256+
// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
257+
// CHECK-FIXES: s.starts_with("aaa");
258+
259+
s.find("aaa", ZERO, strlen(("aaa"))) == ZERO;
260+
// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
261+
// CHECK-FIXES: s.starts_with("aaa");
262+
263+
s.rfind("aaa", 0, 3) != 0;
264+
// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
265+
// CHECK-FIXES: !s.starts_with("aaa");
266+
267+
s.rfind("aaa", ZERO, 3) != 0;
268+
// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
269+
// CHECK-FIXES: !s.starts_with("aaa");
270+
271+
s.rfind("aaa", ZERO, strlen(("aaa"))) == ZERO;
272+
// CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with
273+
// CHECK-FIXES: s.starts_with("aaa");
274+
251275
struct S {
252276
std::string s;
253277
} t;
@@ -274,8 +298,11 @@ void test(std::string s, std::string_view sv, sub_string ss, sub_sub_string sss,
274298
#define STRING s
275299
if (0 == STRING.find("ala")) { /* do something */}
276300

277-
s.find("aaa", 0, 3) == 0;
278-
s.rfind("aaa", std::string::npos, 3) == 0;
301+
// Cases when literal-size and size parameters are different are not being matched.
302+
s.find("aaa", 0, 2) == 0;
303+
s.find("aaa", 0, strlen("aa")) == 0;
304+
s.rfind("aaa", 0, 2) == 0;
305+
s.rfind("aaa", 0, strlen("aa")) == 0;
279306
}
280307

281308
void test_substr() {

0 commit comments

Comments
 (0)