diff --git a/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp b/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp --- a/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp @@ -26,14 +26,20 @@ 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; } diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -188,6 +188,10 @@ ` to support for-loops with iterators initialized by free functions like ``begin``, ``end``, or ``size``. +- Improved :doc:`performance-faster-string-find + ` check to properly escape + single quotes. + - Improved :doc:`performanc-noexcept-swap ` check to enforce a stricter match with the swap function signature, eliminating false-positives. diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp @@ -56,13 +56,21 @@ // 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