[clang-tools-extra] 3717264 - [clang-tidy] Fix invalid avoid-c-style-cast fix-it after keywords (#206239)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Jun 27 20:58:17 PDT 2026
Author: Zeyi Xu
Date: 2026-06-28T11:58:12+08:00
New Revision: 3717264cc34242cc9734d94ecd131f8af02c12a8
URL: https://github.com/llvm/llvm-project/commit/3717264cc34242cc9734d94ecd131f8af02c12a8
DIFF: https://github.com/llvm/llvm-project/commit/3717264cc34242cc9734d94ecd131f8af02c12a8.diff
LOG: [clang-tidy] Fix invalid avoid-c-style-cast fix-it after keywords (#206239)
When a C-style cast immediately follows an identifier-like token, the
replacement could merge with the previous token, e.g. turning
`return(int)d` into `returnstatic_cast<int>(d)`. This patch fixes the
problem by adding a leading space to the replacement when needed.
Closes https://github.com/llvm/llvm-project/issues/97012
Added:
Modified:
clang-tools-extra/clang-tidy/modernize/AvoidCStyleCastCheck.cpp
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-c-style-cast.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidCStyleCastCheck.cpp b/clang-tools-extra/clang-tidy/modernize/AvoidCStyleCastCheck.cpp
index 7010b8774deca..abf2d4ccb077b 100644
--- a/clang-tools-extra/clang-tidy/modernize/AvoidCStyleCastCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/AvoidCStyleCastCheck.cpp
@@ -69,6 +69,28 @@ static CharSourceRange getReplaceRange(const ExplicitCastExpr *Expr) {
llvm_unreachable("Unsupported CastExpr");
}
+static bool needsLeadingSpace(CharSourceRange Range, StringRef ReplacementText,
+ const SourceManager &SM,
+ const LangOptions &LangOpts) {
+ if (ReplacementText.empty())
+ return false;
+
+ const SourceLocation Begin = Range.getBegin();
+ if (Begin.isInvalid() || Begin.isMacroID())
+ return false;
+
+ auto BeginInfo = SM.getDecomposedLoc(Begin);
+ bool Invalid = false;
+ StringRef Buffer = SM.getBufferData(BeginInfo.first, &Invalid);
+ if (Invalid || BeginInfo.second == 0)
+ return false;
+
+ return Lexer::isAsciiIdentifierContinueChar(Buffer[BeginInfo.second - 1],
+ LangOpts) &&
+ Lexer::isAsciiIdentifierContinueChar(ReplacementText.front(),
+ LangOpts);
+}
+
static StringRef getDestTypeString(const SourceManager &SM,
const LangOptions &LangOpts,
const ExplicitCastExpr *Expr) {
@@ -196,6 +218,8 @@ void AvoidCStyleCastCheck::check(const MatchFinder::MatchResult &Result) {
getLangOpts()),
")");
}
+ if (needsLeadingSpace(ReplaceRange, CastText, SM, getLangOpts()))
+ CastText.insert(CastText.begin(), ' ');
Diag << FixItHint::CreateReplacement(ReplaceRange, CastText);
};
auto ReplaceWithNamedCast = [&](StringRef CastType) {
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 81e5de4e0a868..f6026a0c43ed1 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -601,6 +601,11 @@ Changes in existing checks
Because it only sees one file at a time, the check can't be sure
such entities aren't referenced in any other files of that module.
+- Improved :doc:`modernize-avoid-c-style-cast
+ <clang-tidy/checks/modernize/avoid-c-style-cast>` check by fixing an invalid
+ fix-it generated when replacing casts that directly follow a keyword or
+ identifier.
+
- Improved :doc:`modernize-deprecated-headers
<clang-tidy/checks/modernize/deprecated-headers>` check by avoiding false
positives on project headers that use the same name as a standard library
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-c-style-cast.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-c-style-cast.cpp
index 52b4d471bda9b..4b30d67b3b82e 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-c-style-cast.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/avoid-c-style-cast.cpp
@@ -156,6 +156,12 @@ void f(int a, double b, const char *cpc, const void *cpv, X *pX) {
return (void)g();
}
+int cast_after_return(double d) {
+ return(int)d;
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: C-style casts are discouraged; use static_cast [
+ // CHECK-FIXES: return static_cast<int>(d);
+}
+
template <typename T>
void template_function(T t, int n) {
int i = (int)t;
More information about the cfe-commits
mailing list