Skip to content

Commit 5b95d17

Browse files
committed
[clang-tidy] performance-faster-string-find generates incorrect fixes for single quote character literals
Reviewed By: PiotrZSL Differential Revision: https://reviews.llvm.org/D157436
1 parent c5f8110 commit 5b95d17

File tree

3 files changed

+25
-7
lines changed

3 files changed

+25
-7
lines changed

clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,20 @@ std::optional<std::string> makeCharacterLiteral(const StringLiteral *Literal) {
2626
Literal->outputString(OS);
2727
}
2828
// Now replace the " with '.
29-
auto Pos = Result.find_first_of('"');
30-
if (Pos == Result.npos)
29+
auto OpenPos = Result.find_first_of('"');
30+
if (OpenPos == Result.npos)
3131
return std::nullopt;
32-
Result[Pos] = '\'';
33-
Pos = Result.find_last_of('"');
34-
if (Pos == Result.npos)
32+
Result[OpenPos] = '\'';
33+
34+
auto ClosePos = Result.find_last_of('"');
35+
if (ClosePos == Result.npos)
3536
return std::nullopt;
36-
Result[Pos] = '\'';
37+
Result[ClosePos] = '\'';
38+
39+
// "'" is OK, but ''' is not, so add a backslash
40+
if ((ClosePos - OpenPos) == 2 && Result[OpenPos + 1] == '\'')
41+
Result.replace(OpenPos + 1, 1, "\\'");
42+
3743
return Result;
3844
}
3945

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,10 @@ Changes in existing checks
188188
<clang-tidy/checks/modernize/loop-convert>` to support for-loops with
189189
iterators initialized by free functions like ``begin``, ``end``, or ``size``.
190190

191+
- Improved :doc:`performance-faster-string-find
192+
<clang-tidy/checks/performance/faster-string-find>` check to properly escape
193+
single quotes.
194+
191195
- Improved :doc:`performanc-noexcept-swap
192196
<clang-tidy/checks/performance/noexcept-swap>` check to enforce a stricter
193197
match with the swap function signature, eliminating false-positives.

clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,21 @@ void StringFind() {
5656
// CHECK-MESSAGES: [[@LINE-1]]:12: warning: 'find' called with a string literal
5757
// CHECK-FIXES: Str.find('a', 1);
5858

59-
// Doens't work with strings smaller or larger than 1 char.
59+
// Doesn't work with strings smaller or larger than 1 char.
6060
Str.find("");
6161
Str.find("ab");
6262

6363
// Doesn't do anything with the 3 argument overload.
6464
Str.find("a", 1, 1);
6565

66+
// Single quotes are escaped properly
67+
Str.find("'");
68+
// CHECK-MESSAGES: [[@LINE-1]]:12: warning: 'find' called with a string literal
69+
// CHECK-FIXES: Str.find('\'');
70+
Str.find("\'");
71+
// CHECK-MESSAGES: [[@LINE-1]]:12: warning: 'find' called with a string literal
72+
// CHECK-FIXES: Str.find('\'');
73+
6674
// Other methods that can also be replaced
6775
Str.rfind("a");
6876
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: 'rfind' called with a string literal

0 commit comments

Comments
 (0)