https://github.com/vadikmironov updated https://github.com/llvm/llvm-project/pull/184022
>From 71d6e94c1c757373140e8d3911abaf000f9de989 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 | 9 +++++++-- clang-tools-extra/docs/ReleaseNotes.rst | 5 +++++ .../checkers/modernize/use-trailing-return-type.cpp | 11 +++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp index 8ff94709d2529..a09c5e82e8a08 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp @@ -270,8 +270,13 @@ 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()) { + // Cannot handle function-like macros or builtin macros. + // Builtin macros like __has_feature, __has_builtin, etc. are + // registered as object-like macros but expect function-like syntax + // (parenthesized arguments) when expanded. Feeding them to + // classifyToken() would cause the preprocessor to emit spurious + // "missing '(' after '...'" errors. return std::nullopt; } } diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 6bdc0ae7bdcc8..7232fedc67e1c 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -240,6 +240,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
