https://github.com/vadikmironov updated https://github.com/llvm/llvm-project/pull/184022
>From a28a1fa5f963a1b35ff264b71169c6411c42b301 Mon Sep 17 00:00:00 2001 From: Vadim Mironov <[email protected]> Date: Sun, 1 Mar 2026 18:15:07 +0000 Subject: [PATCH] [clang-tidy] Fix spurious errors from builtin macros in modernize-use-trailing-return-type `classifyTokensBeforeFunctionName()` raw-lexes tokens between a function's begin location and its name. When it encounters a macro identifier, it checks `!MI || MI->isFunctionLike()` to bail out for function-like macros that cannot be safely classified. Builtin macros like `__has_feature`, `__has_builtin`, `__has_extension`, etc. are registered via `RegisterBuiltinMacro()` as object-like (`isFunctionLike() == false`), but they expect function-like syntax (parenthesized arguments) when expanded by the preprocessor. The existing filter missed them, allowing them to reach `classifyToken()` which enters `{Tok, EOF}` into the preprocessor token stream. `PP.Lex()` then tries to expand the builtin, expects an opening parenthesis, finds EOF, and emits a spurious diagnostic: error: missing '(' after '__has_feature' This was reported as issue #168360, which was closed because LLVM 22+ happens to match fewer system-header functions (reducing the chance of hitting the buggy path). The underlying defect remained, and any function whose return-type tokens include a builtin macro can still trigger it. The fix adds `MI->isBuiltinMacro()` to the existing bail-out condition. Fixes #168360 Co-Authored-By: Claude Opus 4.6 <[email protected]> --- .../modernize/UseTrailingReturnTypeCheck.cpp | 3 +-- clang-tools-extra/docs/ReleaseNotes.rst | 5 +++++ .../checkers/modernize/use-trailing-return-type.cpp | 11 +++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp index a87fb6cff937a..32aec60da58bb 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp @@ -269,8 +269,7 @@ classifyTokensBeforeFunctionName(const FunctionDecl &F, const ASTContext &Ctx, if (Info.hasMacroDefinition()) { const MacroInfo *MI = PP->getMacroInfo(&Info); - if (!MI || MI->isFunctionLike()) { - // Cannot handle function style macros. + if (!MI || MI->isFunctionLike() || MI->isBuiltinMacro()) { return std::nullopt; } } diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index b0b4cd646c3bd..8a55b55949e54 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -265,6 +265,11 @@ Changes in existing checks <clang-tidy/checks/modernize/use-std-format>` check by fixing a crash when an argument is part of a macro expansion. +- Improved :doc:`modernize-use-trailing-return-type + <clang-tidy/checks/modernize/use-trailing-return-type>` check by fixing + spurious ``missing '(' after '__has_feature'`` errors caused by builtin + macros appearing in the return type of a function. + - Improved :doc:`modernize-use-using <clang-tidy/checks/modernize/use-using>` check by avoiding the generation of invalid code for function types with redundant parentheses. diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type.cpp index 6c919409467d6..3b59860e2f7c8 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type.cpp @@ -487,6 +487,17 @@ decltype(COMMAND_LINE_INT{}) h21(); // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: use a trailing return type for this function [modernize-use-trailing-return-type] // CHECK-FIXES: auto h21() -> decltype(COMMAND_LINE_INT{}); +// Builtin macros like __has_feature are registered as object-like macros but +// require function-like syntax when expanded. Ensure the check does not cause +// spurious "missing '(' after '__has_feature'" errors when they appear in the +// raw lex span of a function return type. +const decltype(__has_feature(cxx_constexpr)) h22(); +// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: use a trailing return type for this function [modernize-use-trailing-return-type] +// CHECK-FIXES: const decltype(__has_feature(cxx_constexpr)) h22(); +const decltype(__has_builtin(__builtin_expect)) h23(); +// CHECK-MESSAGES: :[[@LINE-1]]:49: warning: use a trailing return type for this function [modernize-use-trailing-return-type] +// CHECK-FIXES: const decltype(__has_builtin(__builtin_expect)) h23(); + // // Name collisions // _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
