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; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
