https://github.com/vadikmironov updated 
https://github.com/llvm/llvm-project/pull/184022

>From 46c63b574870314178c02e018a89246f16314323 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]>
---
 .../clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp  | 9 +++++++--
 clang-tools-extra/docs/ReleaseNotes.rst                  | 5 +++++
 .../checkers/modernize/use-trailing-return-type.cpp      | 9 +++++++++
 3 files changed, 21 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..5f6e387ada423 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,15 @@ 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]
+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]
+
 //
 // Name collisions
 //

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to