[clang] [Clang][Preprocessor] Expand UCNs in macro concatenation (PR #145351)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 23 09:03:51 PDT 2025
https://github.com/yronglin created https://github.com/llvm/llvm-project/pull/145351
Fixs https://github.com/llvm/llvm-project/issues/145240.
>From 4892892f8a40c7fe3ebf58fcdb488a08b1eadd91 Mon Sep 17 00:00:00 2001
From: yronglin <yronglin777 at gmail.com>
Date: Tue, 24 Jun 2025 00:00:52 +0800
Subject: [PATCH] [Clang][Preprocessor] Expand UCNs in macro concatenation
Signed-off-by: yronglin <yronglin777 at gmail.com>
---
clang/docs/ReleaseNotes.rst | 1 +
clang/lib/Lex/TokenLexer.cpp | 11 +++++++++++
clang/test/Preprocessor/macro_paste_identifier_ucn.c | 10 ++++++++++
3 files changed, 22 insertions(+)
create mode 100644 clang/test/Preprocessor/macro_paste_identifier_ucn.c
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 96477ef6ddc9a..af107a2d51062 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -720,6 +720,7 @@ Bug Fixes in This Version
- Fixed incorrect token location when emitting diagnostics for tokens expanded from macros. (#GH143216)
- Fixed an infinite recursion when checking constexpr destructors. (#GH141789)
- Fixed a crash when a malformed using declaration appears in a ``constexpr`` function. (#GH144264)
+- Fixed a bug when use unicode character name in macro concatenation. (#GH145240)
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Lex/TokenLexer.cpp b/clang/lib/Lex/TokenLexer.cpp
index 6e93416e01c0c..72f1ffa7ed06e 100644
--- a/clang/lib/Lex/TokenLexer.cpp
+++ b/clang/lib/Lex/TokenLexer.cpp
@@ -748,6 +748,7 @@ bool TokenLexer::pasteTokens(Token &LHSTok, ArrayRef<Token> TokenStream,
const char *ResultTokStrPtr = nullptr;
SourceLocation StartLoc = LHSTok.getLocation();
SourceLocation PasteOpLoc;
+ bool HasUCNs = false;
auto IsAtEnd = [&TokenStream, &CurIdx] {
return TokenStream.size() == CurIdx;
@@ -885,6 +886,9 @@ bool TokenLexer::pasteTokens(Token &LHSTok, ArrayRef<Token> TokenStream,
// Finally, replace LHS with the result, consume the RHS, and iterate.
++CurIdx;
+
+ // Set Token::HasUCN flag if LHS or RHS contains any UCNs.
+ HasUCNs = LHSTok.hasUCN() || RHS.hasUCN() || HasUCNs;
LHSTok = Result;
} while (!IsAtEnd() && TokenStream[CurIdx].is(tok::hashhash));
@@ -913,6 +917,13 @@ bool TokenLexer::pasteTokens(Token &LHSTok, ArrayRef<Token> TokenStream,
// token pasting re-lexes the result token in raw mode, identifier information
// isn't looked up. As such, if the result is an identifier, look up id info.
if (LHSTok.is(tok::raw_identifier)) {
+
+ // If there has any UNCs in concated token, we should mark this token
+ // with Token::HasUCN flag, then LookUpIdentifierInfo will expand UCNs in
+ // token.
+ if (HasUCNs)
+ LHSTok.setFlag(Token::HasUCN);
+
// Look up the identifier info for the token. We disabled identifier lookup
// by saying we're skipping contents, so we need to do this manually.
PP.LookUpIdentifierInfo(LHSTok);
diff --git a/clang/test/Preprocessor/macro_paste_identifier_ucn.c b/clang/test/Preprocessor/macro_paste_identifier_ucn.c
new file mode 100644
index 0000000000000..c9eb8190edfe8
--- /dev/null
+++ b/clang/test/Preprocessor/macro_paste_identifier_ucn.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fms-extensions %s -verify
+// RUN: %clang_cc1 -E -fms-extensions %s | FileCheck %s
+// expected-no-diagnostics
+
+#define CAT(a,b) a##b
+
+char foo\u00b5;
+char*p = &CAT(foo, \u00b5);
+// CHECK: char fooµ;
+// CHECK-NEXT: char*p = &fooµ;
More information about the cfe-commits
mailing list