[clang] 235056b - [clang][Preprocessor] Fix expansion locations for feature-like builtin macros (#207130)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 10 05:29:02 PDT 2026
Author: Macro Terra
Date: 2026-07-10T08:28:57-04:00
New Revision: 235056b9efea87a1a7fa0d36f94e56a44dbd920b
URL: https://github.com/llvm/llvm-project/commit/235056b9efea87a1a7fa0d36f94e56a44dbd920b
DIFF: https://github.com/llvm/llvm-project/commit/235056b9efea87a1a7fa0d36f94e56a44dbd920b.diff
LOG: [clang][Preprocessor] Fix expansion locations for feature-like builtin macros (#207130)
Fixes #196067.
This patch fixes the expansion locations of synthesized tokens produced
by
feature-like builtin macros such as `__has_builtin(...)`.
Feature-like builtin macros lex past the macro name while evaluating
their
arguments. `ExpandBuiltinMacro()` used the final `Tok` location as both
the
expansion start and end when creating the synthesized result token, so
`__has_builtin(...)` results were anchored at the closing paren rather
than the
builtin macro invocation.
Fix by saving the macro-name location before argument parsing and using
it as
the expansion start. The expansion end remains the final `Tok` location.
Add a `syntax::TokenCollector` regression test for a valid
`__has_builtin(...)`
expansion and the `__is_identifier;` recovery path.
Tested:
`ninja -C /home/ubuntu2404/build-196067-assert check-clang`
Total Discovered Tests: 52396
Skipped: 6
Unsupported: 5782
Passed: 46582
Expectedly Failed: 26
Assisted-by: OpenAI Codex
Added:
Modified:
clang/docs/ReleaseNotes.md
clang/lib/Lex/PPMacroExpansion.cpp
clang/unittests/Tooling/Syntax/TokensTest.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 5a321cdb7e3cd..7f0a28acd2ade 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -790,6 +790,9 @@ latest release, please see the [Clang Web Site](https://clang.llvm.org) or the
- Fixed `clang::Preprocessor::recomputeCurLexerKind` to avoid default fallback to `CurLexerCallback = CLK_CachingLexer;`. This prevents code-completion
EOF handling from accidentally restoring CLK_CachingLexer while a tentative parse is still active, which could trigger a caching lexer re-entry assertion
in clangd signature help. (#GH200677)
+- Fixed incorrect expansion source ranges for synthesized tokens produced by
+ feature-like builtin macros such as `__has_builtin`, which could trigger
+ assertions in syntax token collection. (#GH196067)
- Fixed a crash when `#embed` is used with C++ modules (#GH195350)
- Fixed an assertion in constant evaluation when using a defaulted comparison operator in a `union`. (#GH147127)
- Fixed a bug where `-x cuda` caused clang to immediately resolve templates that should not be. (#GH200545)
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index 23a21f42b8e3a..e09e80a063c4e 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -1619,6 +1619,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
// Figure out which token this is.
IdentifierInfo *II = Tok.getIdentifierInfo();
assert(II && "Can't be a macro without id info!");
+ SourceLocation MacroNameLoc = Tok.getLocation();
// If this is an _Pragma or Microsoft __pragma directive, expand it,
// invoke the pragma handler, then lex the token after it.
@@ -2096,7 +2097,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
} else {
llvm_unreachable("Unknown identifier!");
}
- CreateString(OS.str(), Tok, Tok.getLocation(), Tok.getLocation());
+ CreateString(OS.str(), Tok, MacroNameLoc, Tok.getLocation());
Tok.setFlagValue(Token::StartOfLine, IsAtStartOfLine);
Tok.setFlagValue(Token::LeadingSpace, HasLeadingSpace);
Tok.clearFlag(Token::NeedsCleaning);
diff --git a/clang/unittests/Tooling/Syntax/TokensTest.cpp b/clang/unittests/Tooling/Syntax/TokensTest.cpp
index ae5001a2f5645..6418cc8f87d9d 100644
--- a/clang/unittests/Tooling/Syntax/TokensTest.cpp
+++ b/clang/unittests/Tooling/Syntax/TokensTest.cpp
@@ -552,6 +552,18 @@ file './input.cpp'
}
}
+TEST_F(TokenCollectorTest, FeatureLikeBuiltinMacros) {
+ recordTokens("__has_builtin(__builtin_allow_runtime_check)\n");
+ EXPECT_THAT(Buffer.expandedTokens(),
+ ElementsAre(AllOf(Kind(tok::numeric_constant), HasText("1")),
+ Kind(tok::eof)));
+ auto ExpansionRange =
+ SourceMgr->getExpansionRange(findExpanded("1").front().location());
+ EXPECT_EQ(findSpelled("__has_builtin").front().location(),
+ ExpansionRange.getBegin());
+ EXPECT_EQ(findSpelled(")").front().location(), ExpansionRange.getEnd());
+}
+
TEST_F(TokenCollectorTest, SpecialTokens) {
// Tokens coming from concatenations.
recordTokens(R"cpp(
More information about the cfe-commits
mailing list