[clang-tools-extra] [clang-tidy]fix incorrect auto-fix for the string contains a user-defined suffix (PR #122901)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 14 05:38:33 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-tools-extra
Author: Congcong Cai (HerrCai0907)
<details>
<summary>Changes</summary>
Fixed: #<!-- -->97243
---
Full diff: https://github.com/llvm/llvm-project/pull/122901.diff
4 Files Affected:
- (modified) clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.cpp (+21-7)
- (modified) clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.h (+1-1)
- (modified) clang-tools-extra/docs/ReleaseNotes.rst (+4)
- (modified) clang-tools-extra/test/clang-tidy/checkers/modernize/raw-string-literal.cpp (+13)
``````````diff
diff --git a/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.cpp b/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.cpp
index 7ec62f41aec019..bd9830278facb7 100644
--- a/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.cpp
@@ -10,6 +10,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/StringRef.h"
using namespace clang::ast_matchers;
@@ -136,13 +137,26 @@ void RawStringLiteralCheck::check(const MatchFinder::MatchResult &Result) {
void RawStringLiteralCheck::replaceWithRawStringLiteral(
const MatchFinder::MatchResult &Result, const StringLiteral *Literal,
- StringRef Replacement) {
- CharSourceRange CharRange = Lexer::makeFileCharRange(
- CharSourceRange::getTokenRange(Literal->getSourceRange()),
- *Result.SourceManager, getLangOpts());
- diag(Literal->getBeginLoc(),
- "escaped string literal can be written as a raw string literal")
- << FixItHint::CreateReplacement(CharRange, Replacement);
+ std::string Replacement) {
+ DiagnosticBuilder Builder =
+ diag(Literal->getBeginLoc(),
+ "escaped string literal can be written as a raw string literal");
+ const SourceManager &SM = *Result.SourceManager;
+ const CharSourceRange TokenRange =
+ CharSourceRange::getTokenRange(Literal->getSourceRange());
+ Token T;
+ if (Lexer::getRawToken(Literal->getBeginLoc(), T, SM, getLangOpts()))
+ return;
+ const CharSourceRange CharRange =
+ Lexer::makeFileCharRange(TokenRange, SM, getLangOpts());
+ if (T.hasUDSuffix()) {
+ StringRef Text = Lexer::getSourceText(CharRange, SM, getLangOpts());
+ const size_t UDSuffixPos = Text.find_last_of('"');
+ if (UDSuffixPos == StringRef::npos)
+ return;
+ Replacement += Text.slice(UDSuffixPos + 1, Text.size());
+ }
+ Builder << FixItHint::CreateReplacement(CharRange, Replacement);
}
} // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.h b/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.h
index aae58ca0e98d9a..6898e0624d1eb8 100644
--- a/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.h
@@ -35,7 +35,7 @@ class RawStringLiteralCheck : public ClangTidyCheck {
private:
void replaceWithRawStringLiteral(
const ast_matchers::MatchFinder::MatchResult &Result,
- const StringLiteral *Literal, StringRef Replacement);
+ const StringLiteral *Literal, std::string Replacement);
std::string DelimiterStem;
CharsBitSet DisallowedChars;
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 3fe2f0ce01bccd..503d16bae021a8 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -317,6 +317,10 @@ Changes in existing checks
a false positive when only an implicit conversion happened inside an
initializer list.
+- Improved :doc:`modernize-raw-string-literal
+ <clang-tidy/checks/modernize/raw-string-literal>` check to fix incorrect auto
+ fix when the string contains a user-defined suffix.
+
- Improved :doc:`modernize-use-designated-initializers
<clang-tidy/checks/modernize/use-designated-initializers>` check to fix a
crash when a class is declared but not defined.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/raw-string-literal.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/raw-string-literal.cpp
index ad5d450036f2fd..5856b8882574a7 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/raw-string-literal.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/raw-string-literal.cpp
@@ -129,3 +129,16 @@ void callFn() {
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} can be written as a raw string literal
// CHECK-FIXES: {{^}} fn<double>(R"(foo\bar)");{{$}}
}
+
+namespace std {
+using size_t = decltype(sizeof(0));
+namespace ud {
+int operator""_abc(const char *str, std::size_t len);
+} // namespace ud
+} // namespace std
+namespace gh97243 {
+using namespace std::ud;
+auto UserDefinedLiteral = "foo\\bar"_abc;
+// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}auto UserDefinedLiteral = R"(foo\bar)"_abc;
+} // namespace gh97243
``````````
</details>
https://github.com/llvm/llvm-project/pull/122901
More information about the cfe-commits
mailing list