[clang-tidy] performance-faster-string-find generates incorrect fixes for single quote character literals

Reviewed By: PiotrZSL

Differential Revision: https://reviews.llvm.org/D157436
This commit is contained in:
Fabian Wolff 2023-08-09 00:55:45 +02:00
parent c5f81100e4
commit 5b95d17da1
3 changed files with 25 additions and 7 deletions

View File

@ -26,14 +26,20 @@ std::optional<std::string> makeCharacterLiteral(const StringLiteral *Literal) {
Literal->outputString(OS);
}
// Now replace the " with '.
auto Pos = Result.find_first_of('"');
if (Pos == Result.npos)
auto OpenPos = Result.find_first_of('"');
if (OpenPos == Result.npos)
return std::nullopt;
Result[Pos] = '\'';
Pos = Result.find_last_of('"');
if (Pos == Result.npos)
Result[OpenPos] = '\'';
auto ClosePos = Result.find_last_of('"');
if (ClosePos == Result.npos)
return std::nullopt;
Result[Pos] = '\'';
Result[ClosePos] = '\'';
// "'" is OK, but ''' is not, so add a backslash
if ((ClosePos - OpenPos) == 2 && Result[OpenPos + 1] == '\'')
Result.replace(OpenPos + 1, 1, "\\'");
return Result;
}

View File

@ -188,6 +188,10 @@ Changes in existing checks
<clang-tidy/checks/modernize/loop-convert>` to support for-loops with
iterators initialized by free functions like ``begin``, ``end``, or ``size``.
- Improved :doc:`performance-faster-string-find
<clang-tidy/checks/performance/faster-string-find>` check to properly escape
single quotes.
- Improved :doc:`performanc-noexcept-swap
<clang-tidy/checks/performance/noexcept-swap>` check to enforce a stricter
match with the swap function signature, eliminating false-positives.

View File

@ -56,13 +56,21 @@ void StringFind() {
// CHECK-MESSAGES: [[@LINE-1]]:12: warning: 'find' called with a string literal
// CHECK-FIXES: Str.find('a', 1);
// Doens't work with strings smaller or larger than 1 char.
// Doesn't work with strings smaller or larger than 1 char.
Str.find("");
Str.find("ab");
// Doesn't do anything with the 3 argument overload.
Str.find("a", 1, 1);
// Single quotes are escaped properly
Str.find("'");
// CHECK-MESSAGES: [[@LINE-1]]:12: warning: 'find' called with a string literal
// CHECK-FIXES: Str.find('\'');
Str.find("\'");
// CHECK-MESSAGES: [[@LINE-1]]:12: warning: 'find' called with a string literal
// CHECK-FIXES: Str.find('\'');
// Other methods that can also be replaced
Str.rfind("a");
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: 'rfind' called with a string literal