[clang-tools-extra] [clang-tidy] Detect string literals in macros in modernize-raw-string… (PR #133636)
Carlos Galvez via cfe-commits
cfe-commits at lists.llvm.org
Sun Mar 30 05:27:51 PDT 2025
https://github.com/carlosgalvezp created https://github.com/llvm/llvm-project/pull/133636
…-literal
Fixes #133618
>From 2baffdbd656723b15370d3dd3560f3bd62262664 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Carlos=20G=C3=A1lvez?= <carlos.galvez at zenseact.com>
Date: Sun, 30 Mar 2025 12:24:32 +0000
Subject: [PATCH] [clang-tidy] Detect string literals in macros in
modernize-raw-string-literal
Fixes #133618
---
.../clang-tidy/modernize/RawStringLiteralCheck.cpp | 11 ++++++-----
clang-tools-extra/docs/ReleaseNotes.rst | 4 ++++
.../checkers/modernize/raw-string-literal.cpp | 3 ++-
3 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.cpp b/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.cpp
index 24674a407cb36..1be0d6cc23935 100644
--- a/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.cpp
@@ -58,7 +58,7 @@ bool containsEscapedCharacters(const MatchFinder::MatchResult &Result,
*Result.SourceManager, Result.Context->getLangOpts());
StringRef Text = Lexer::getSourceText(CharRange, *Result.SourceManager,
Result.Context->getLangOpts());
- if (Text.empty() || isRawStringLiteral(Text))
+ if (Text.empty() || !Text.contains('"') || isRawStringLiteral(Text))
return false;
return containsEscapes(Text, R"('\"?x01)");
@@ -156,14 +156,14 @@ static bool compareStringLength(StringRef Replacement,
const SourceManager &SM,
const LangOptions &LangOpts) {
return Replacement.size() <=
- Lexer::MeasureTokenLength(Literal->getBeginLoc(), SM, LangOpts);
+ Lexer::MeasureTokenLength(SM.getSpellingLoc(Literal->getBeginLoc()), SM, LangOpts);
}
void RawStringLiteralCheck::check(const MatchFinder::MatchResult &Result) {
const auto *Literal = Result.Nodes.getNodeAs<StringLiteral>("lit");
- if (Literal->getBeginLoc().isMacroID())
- return;
const SourceManager &SM = *Result.SourceManager;
+ if (SM.getSpellingLoc(Literal->getBeginLoc()).isMacroID())
+ return;
const LangOptions &LangOpts = getLangOpts();
if (containsEscapedCharacters(Result, Literal, DisallowedChars)) {
const std::string Replacement =
@@ -172,7 +172,8 @@ void RawStringLiteralCheck::check(const MatchFinder::MatchResult &Result) {
compareStringLength(Replacement, Literal, SM, LangOpts)) {
diag(Literal->getBeginLoc(),
"escaped string literal can be written as a raw string literal")
- << FixItHint::CreateReplacement(Literal->getSourceRange(),
+ << FixItHint::CreateReplacement(SourceRange(SM.getSpellingLoc(Literal->getBeginLoc()),
+ SM.getSpellingLoc(Literal->getEndLoc())),
Replacement);
}
}
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 6cb8d572d3a78..c7c5ac75986be 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -181,6 +181,10 @@ Changes in existing checks
<clang-tidy/checks/modernize/use-std-numbers>` check to support math
functions of different precisions.
+- Improved :doc:`modernize-raw-string-literal
+ <clang-tidy/checks/modernize/raw-string-literal>` check to detect string
+ literals passed into macros.
+
- Improved :doc:`performance-move-const-arg
<clang-tidy/checks/performance/move-const-arg>` check by fixing false
negatives on ternary operators calling ``std::move``.
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 5856b8882574a..fc4e966e92e07 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
@@ -105,7 +105,8 @@ char const *const StringizedMacroArgument = HAT(foo\\bar);
#define SUBST(lit_) lit_
char const *const MacroArgument = SUBST("foo\\bar");
-// FIXME: We should be able to replace this string literal macro argument
+// CHECK-MESSAGES: :[[@LINE-1]]:41: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const MacroArgument = SUBST(R"(foo\bar)");{{$}}
template <typename T>
void fn(char const *const Arg) {
More information about the cfe-commits
mailing list