[clang] [clang][Lex] Don't parsing header name as a string literal (PR #201763)
Yihan Wang via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 5 09:28:35 PDT 2026
https://github.com/yronglin updated https://github.com/llvm/llvm-project/pull/201763
>From 1cf3e8c5585822087a38f79d455c96ddf1227afc Mon Sep 17 00:00:00 2001
From: yronglin <yronglin777 at gmail.com>
Date: Thu, 4 Jun 2026 23:29:41 -0700
Subject: [PATCH 1/3] [clang][Lex] Don't parsing header name as a string
literal
Signed-off-by: yronglin <yronglin777 at gmail.com>
---
clang/lib/Lex/Lexer.cpp | 21 ++++++++++++++++++++-
clang/test/CXX/lex/lex.header/p2.cpp | 5 +++++
2 files changed, 25 insertions(+), 1 deletion(-)
create mode 100644 clang/test/CXX/lex/lex.header/p2.cpp
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index 2797212c229f5..40a1e6811b069 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -2279,9 +2279,28 @@ bool Lexer::LexStringLiteral(Token &Result, const char *CurPtr,
while (C != '"') {
// Skip escaped characters. Escaped newlines will already be processed by
// getAndAdvanceChar.
- if (C == '\\')
+ if (C == '\\') {
+ const char *SavedCurPtr = CurPtr;
C = getAndAdvanceChar(CurPtr, Result);
+ // lex.header
+ //
+ // header-name:
+ // ...
+ // " q-char-sequence "
+ // ...
+ // q-char-sequence:
+ // q-char q-char-sequence[opt]
+ // q-char:
+ // any member of the translation character set except new-line and U+0022 quotation mark
+ //
+ // The implementation-defined semantics cannot be taken as causing '\' to
+ // "escape" the following " because there is no provision for " in a
+ // q-char-sequence.
+ if (ParsingFilename && C == '"')
+ CurPtr = SavedCurPtr;
+ }
+
if (C == '\n' || C == '\r' || // Newline.
(C == 0 && CurPtr-1 == BufferEnd)) { // End of file.
if (!isLexingRawMode() && !LangOpts.AsmPreprocessor)
diff --git a/clang/test/CXX/lex/lex.header/p2.cpp b/clang/test/CXX/lex/lex.header/p2.cpp
new file mode 100644
index 0000000000000..76132e610b3ac
--- /dev/null
+++ b/clang/test/CXX/lex/lex.header/p2.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+// expected-no-diagnostics
+
+#if __has_include("\")
+#endif
>From 551320fdb51154a79b3114d7109e06af4dc81446 Mon Sep 17 00:00:00 2001
From: yronglin <yronglin777 at gmail.com>
Date: Thu, 4 Jun 2026 23:36:53 -0700
Subject: [PATCH 2/3] Add release notes
Signed-off-by: yronglin <yronglin777 at gmail.com>
---
clang/docs/ReleaseNotes.rst | 1 +
1 file changed, 1 insertion(+)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 77f801e6f7d67..172fcfde8fcf5 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -666,6 +666,7 @@ Bug Fixes in This Version
- Fixed a crash when ``#embed`` is used with C++ modules (#GH195350)
- Fixed an issue where ``__typeof_unqual`` and ``__typeof_unqual__`` were rejected as a declaration specifier in block scope in C++.
- Fixed crash when checking for overflow for unary operator that can't overflow (#GH170072)
+- Clang now don't handling `" q-char-sequence "` header name as a string literal (#GH132643).
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>From 0a9327ef7f1685767e8ae124f2ee569071827995 Mon Sep 17 00:00:00 2001
From: yronglin <yronglin777 at gmail.com>
Date: Thu, 4 Jun 2026 23:38:28 -0700
Subject: [PATCH 3/3] Format
Signed-off-by: yronglin <yronglin777 at gmail.com>
---
clang/lib/Lex/Lexer.cpp | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index 40a1e6811b069..f52b84a42ca70 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -2284,7 +2284,7 @@ bool Lexer::LexStringLiteral(Token &Result, const char *CurPtr,
C = getAndAdvanceChar(CurPtr, Result);
// lex.header
- //
+ //
// header-name:
// ...
// " q-char-sequence "
@@ -2292,7 +2292,8 @@ bool Lexer::LexStringLiteral(Token &Result, const char *CurPtr,
// q-char-sequence:
// q-char q-char-sequence[opt]
// q-char:
- // any member of the translation character set except new-line and U+0022 quotation mark
+ // any member of the translation character set except new-line and
+ // U+0022 quotation mark
//
// The implementation-defined semantics cannot be taken as causing '\' to
// "escape" the following " because there is no provision for " in a
More information about the cfe-commits
mailing list